// Verschiedene kleine Dialoge:
// nichtmodal: Display - Tabelle - Schaltplan
// modal: Schnittstelle - Search - Transmitter - Intervall - Über
#include <windows.h>
#include <windowsx.h> //message crackers
#ifndef GET_WM_COMMAND_CMD
# define GET_WM_COMMAND_CMD(wp,lp) HIWORD(lp) //fehlt bei BC31 windowsx.h
#endif
#include <stdlib.h> //atoi
#include <stdarg.h> //va_list
#include <stdio.h> //sprintf, sscanf
#include <string.h> //memset
#include <math.h> //floor
#include "driver.h"
#include "dialog.h"
#include "toolstat.h" //HelpFileName
#include "sensokom.rh" //Dialog-IDs für Hilfe
/*=========== Hilfsprogramme WUTILS ===================*/
#define nobreak
int Limit(int x, int u, int o) {
return x<u?u:x>o?o:x;
}
UINT InitStruct(void*str,UINT len) {
memset(str,0,len);
*(UINT*)str=len;
return 0;
}
int pascal vMBox(HWND Wnd, UINT id, UINT style, const void far*arglist) {
char buf1[256],buf2[256];
LoadString(hInstance,id,buf1,sizeof(buf1));
wvsprintf(buf2,buf1,/*WIN32:(va_list)*/arglist);
return MessageBox(Wnd,buf2,"Sensokom",style);
}
int cdecl MBox(HWND Wnd, UINT id, UINT style,...) {
return vMBox(Wnd,id,style,&style+1);
}
void pascal SetEditFocus(HWND Wnd, UINT id) {
Wnd=GetDlgItem(Wnd,id);
Edit_SetSel(Wnd,0,(UINT)-1);
}
int pascal GetRadioCheck(HWND Wnd, UINT idStart,UINT idEnd) {
int result=0;
for (; idStart<=idEnd; idStart++,result++) {
if (IsDlgButtonChecked(Wnd,idStart)==1) return result;
}
return -1;
}
void EnableDlgItem(HWND Wnd, UINT id, BOOL state) {
Wnd=GetDlgItem(Wnd,id);
if (Wnd) EnableWindow(Wnd,state);
}
static BOOL ShiftRect(LPINT r, const LPINT r2) {
// Hilfsfunktion, schiebt horizontal bzw. vertikal
int ax,dx; // jaja, Assembler
ax=r2[0]-r[0]; // Differenz links bzw. oben
if (!ax) return FALSE;
if (ax<0) {
dx=r2[2]-r[2]; // Differenz rechts bzw. unten
if (dx>=0) return FALSE;
if (ax<dx) ax=dx; // die kleinere Zahl
}
r[0]+=ax;
r[2]+=ax;
return TRUE;
}
BOOL MoveRectIntoRect(LPRECT R, const LPRECT R2) {
// Falls R in R2 teilweise oder vollständig außerhalb liegt,
// wird R verschoben und TRUE zurückgeliefert, um maximale Sichtbarkeit
// zu realisieren.
// Dient zum Hineinholen von außerhalb liegenden Fenstern in den Desktop.
return ShiftRect((LPINT)&R->left,(LPINT)&R2->left)
+ShiftRect((LPINT)&R->top, (LPINT)&R2->top);
}
void GetFullScreenRect(LPRECT R) {
// Ermittelt das Rechteck für maximierte Fenster, d.h. die Startleiste
// von Win9x bereits abgezogen, ideal für R2 in MoveRectIntoRect
R->left=R->top=0;
R->right=GetSystemMetrics(SM_CXFULLSCREEN);
R->bottom=GetSystemMetrics(SM_CYFULLSCREEN)+GetSystemMetrics(SM_CYCAPTION);
}
BOOL MoveRectIntoFullScreen(LPRECT R) {
// die logische Kombination beider o.g. Routinen
RECT R2;
GetFullScreenRect(&R2);
return MoveRectIntoRect(R,&R2);
}
#ifdef __BORLANDC__
# pragma argsused
#endif
BOOL _stdcall Line(HDC dc, int x1, int y1, int x2, int y2) {
return Polyline(dc, (LPPOINT)&x1,2);
}
//Das, was Set{Window|Viewport}{Org|Ext} letztlich bewirkt:
int fitrafo(float x, float a, float e, int A, int E) {
//Transformation von FLOAT zu INT, kein Problem bei a=e
e-=a;
if (!e) return 0;
return (int)floor(((x-a)*(E-A)/e)+A+0.5);
}
BOOL GetDlgItemFloat(HWND Wnd, UINT id, float*z) {
// Gleitkommazahl (auch mit Komma statt Punkt) vom Dialogelement holen
char s[32],*sp;
Wnd=GetDlgItem(Wnd,id);
GetWindowText(Wnd,s,sizeof(s));
sp=(char*)lstrchr(s,','); // Ein Komma durch Punkt ersetzen
if (sp) *sp='.';
if (sscanf(s,"%f",z)==1) return TRUE;
SetFocus(Wnd);
Edit_SetSel(Wnd,0,(UINT)-1); // Message Cracker macht den Rest
return FALSE;
}
void SetDlgItemFloat(HWND Wnd, UINT id, int komma, float z) {
// Gleitkommazahl in Dialogelement setzen
char buf[32];
sprintf(buf,"%.*f",komma,z); SetDlgItemText(Wnd,id,buf);
}
HHOOK CallWndHook;
LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam) {
#ifndef _WIN32
typedef struct{
LPARAM lParam;
WPARAM wParam;
UINT message;
HWND hwnd;
}CWPSTRUCT,*PCWPSTRUCT,near*NPCWPSTRUCT,far*LPCWPSTRUCT;
#endif
switch (((LPCWPSTRUCT)lParam)->message) {
case WM_SETCURSOR: {
// case WM_NCMOUSEMOVE: {
// MessageBeep((UINT)-1);
SetCursor(LoadCursor(0,IDC_WAIT));
((LPCWPSTRUCT)lParam)->message=WM_NULL; // verschlucken
}
}
return CallNextHookEx(CallWndHook,code,wParam,lParam);
}
void SetWaitCursor(HWND Wnd, BOOL ShowWait) {
// Sanduhr ein/ausschalten, unbedingt paarweise rufen!
// Die Schwierigkeit des Anzeigens der Sanduhr besteht hier darin,
// dass die langwierigen DDE-Transfers auch per PeekMessage()
// Rechenzeit freigeben. So bekommt das Dialogfenster auch zwischendurch
// WM_MOUSEMOVE-Nachrichten, was die Sanduhr zu kurzlebig machen würde.
// Und dummerweise ist der Mauspfeil eine Klassen- und keine Fenster-
// Eigenschaft - wahrlich ein Konstruktionsfehler von Windows.
EnableWindow(Wnd,!ShowWait);
if (ShowWait) {
CallWndHook=SetWindowsHookEx(WH_CALLWNDPROC,CallWndProc,hInstance,
#ifdef _WIN32
GetCurrentThreadId());
#else
GetCurrentTask());
#endif
}else{
UnhookWindowsHookEx(CallWndHook);
}
ShowCursor(ShowWait);
SendMessage(Wnd,WM_SETCURSOR,(WPARAM)Wnd,HTCLIENT);
}
int iitrafo(int x, int a, int e, int A, int E) {
//Transformation von INT zu INT (mit Rundung), kein Problem bei a=e
e-=a;
if (!e) return 0;
return MulDiv(x-a,E-A,e)+A;
}
long exp10(int e) {
long ret=1;
while (e--) ret*=10;
return ret;
}
extern HWND MainWnd; // eigentlich: toolstat.h
void PlaceDialog(HWND Wnd, PPOINT pt) {
RECT r;
GetWindowRect(Wnd,&r);
r.right-=r.left; r.bottom-=r.top; // Distanzen
*(PPOINT)&r=*pt; // links oben
MapWindowPoints(MainWnd,0,(PPOINT)&r,1); // umsetzen
r.right+=r.left; r.bottom+=r.top; // rechte Kanten
MoveRectIntoFullScreen(&r); // deshalb!
SetWindowPos(Wnd,0,r.left,r.top,0,0,SWP_NOSIZE|SWP_NOZORDER);
}
void OnMoveDialog(HWND Wnd, PPOINT pt) {
RECT r;
GetWindowRect(Wnd,&r);
MapWindowPoints(0,MainWnd,(PPOINT)&r,1); // nur links oben interessant
*pt=*(PPOINT)&r;
}
/*=====================================================*/
HWND DisplayDlg;
POINT DisplayDlgPos; // letzte Platzierung relativ zum Hauptfenster
BOOL CALLBACK DisplayDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
switch (Msg) {
case WM_INITDIALOG: {
PlaceDialog(Wnd,&DisplayDlgPos);
}return TRUE;
case WM_USER: {
if (lParam) SetDlgItemText(Wnd,2001,Get_Messwert((LPSTR)lParam));
}break;
case WM_MOVE: {
OnMoveDialog(Wnd,&DisplayDlgPos);
}break;
case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd);
case WM_DESTROY: DisplayDlg=0; break;
}/*switch*/
return FALSE;
}
/*=====================================================*/
HWND TabelleDlg;
POINT TabelleDlgPos;
BOOL CALLBACK TabelleDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
switch (Msg) {
case WM_INITDIALOG: {
int i;
char AntwortString[32];
SetDlgItemInt(Wnd,3001,(UINT)lParam,FALSE); // Adresse setzen
PlaceDialog(Wnd,&TabelleDlgPos);
i=3; do{ // 3 Versuche
if (ISM_Info((BYTE)lParam,AntwortString,sizeof(AntwortString))) break;
}while (--i);
SetDlgItemText(Wnd,3002,Get_Number(AntwortString));
SetDlgItemText(Wnd,3003,Get_File(AntwortString));
}return TRUE;
case WM_MOVE: {
OnMoveDialog(Wnd,&TabelleDlgPos);
}break;
case WM_USER: if (lParam) {
SetDlgItemText(Wnd,3004,Get_Messwert((LPSTR)lParam));
SetDlgItemInt(Wnd,3005,GetInp((LPSTR)lParam),FALSE);
SetDlgItemInt(Wnd,3006,Get_IO((LPSTR)lParam),FALSE);
SetDlgItemInt(Wnd,3007,GetOut((LPSTR)lParam),FALSE);
}break;
case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd);
case WM_DESTROY: TabelleDlg=0; break;
}/*switch*/
return FALSE;
}
/*=====================================================*/
HWND SchaltplanDlg;
POINT SchaltplanDlgPos;
BOOL CALLBACK SchaltplanDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam){
switch (Msg) {
case WM_INITDIALOG: { //lParam=Messart
PlaceDialog(Wnd,&SchaltplanDlgPos);
SetWindowLong(Wnd,DWL_USER,
(LONG)LoadBitmap(hInstance,MAKEINTRESOURCE(lParam+10)));
}return TRUE;
case WM_MOVE: {
OnMoveDialog(Wnd,&SchaltplanDlgPos);
}break;
case WM_SET_MESSART: { //lParam=neue Messart
DeleteObject((HBITMAP)SetWindowLong(Wnd,DWL_USER,
(LONG)LoadBitmap(hInstance,MAKEINTRESOURCE(lParam+10))));
InvalidateRect(GetDlgItem(Wnd,101),NULL,TRUE);
}break;
case WM_DRAWITEM: {
#define DIS ((LPDRAWITEMSTRUCT)lParam)
BITMAP bm;
HDC MemDC=CreateCompatibleDC(DIS->hDC);
HBITMAP hbm=(HBITMAP)GetWindowLong(Wnd,DWL_USER);
HBITMAP obm=(HBITMAP)SelectObject(MemDC,hbm);
GetObject(hbm,sizeof(bm),&bm); // Größe zum Zentrieren ermitteln
BitBlt(DIS->hDC,
(DIS->rcItem.left+DIS->rcItem.right-bm.bmWidth)/2,
(DIS->rcItem.top+DIS->rcItem.bottom-bm.bmHeight)/2,
bm.bmWidth,bm.bmHeight,MemDC,0,0,SRCCOPY);
SelectObject(MemDC,obm);
DeleteDC(MemDC);
#undef DIS
}break;
case WM_COMMAND: if (LOWORD(wParam)==2) DestroyWindow(Wnd); break;
case WM_DESTROY: {
DeleteObject((HBITMAP)GetWindowLong(Wnd,DWL_USER));
SchaltplanDlg=0;
}break;
}/*switch*/
return FALSE;
}
/*=====================================================*/
BOOL CALLBACK SchnittstelleDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG: {
SetWindowLong(Wnd,DWL_USER,lParam);
CheckDlgButton(Wnd,102,TRUE);
CheckDlgButton(Wnd,1010,TRUE);
if (*(LPSTR)lParam) {
CheckDlgButton(Wnd,105,TRUE);
SetDlgItemText(Wnd,104,(LPSTR)lParam);
SendMessage(Wnd,WM_COMMAND,105,0);
} // sonst "Amarillo" stehen lassen
}return TRUE;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case 105: {
int i;
BOOL Enab=IsDlgButtonChecked(Wnd,105);
EnableDlgItem(Wnd,104,Enab);
Enab=!Enab;
for (i=1005; i<=1012; i++) EnableDlgItem(Wnd,i,Enab);
}break;
case 9: {
WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_SCHNITTSTELLE);
}break;
case 1: {
lParam=GetWindowLong(Wnd,DWL_USER);
SetWaitCursor(Wnd,TRUE);
#define DdeServer ((LPSTR)lParam)
if (IsDlgButtonChecked(Wnd,105)) GetDlgItemText(Wnd,104,DdeServer,32);
else *DdeServer='\0'; // rückschreiben
Com_Init(*DdeServer?DdeServer:NULL,
(WORD)(GetRadioCheck(Wnd,101,103)+1),
(WORD)GetDlgItemInt(Wnd,1005+GetRadioCheck(Wnd,1005,1012),NULL,FALSE));
#undef DdeServer
SetWaitCursor(Wnd,FALSE);
}nobreak;
case 2: EndDialog(Wnd,wParam);
}/*switch*/
}return FALSE;
}/*switch*/
return FALSE;
}
/*=====================================================*/
BOOL CALLBACK SearchDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
static BYTE SuchAdr;
switch (Msg) {
case WM_INITDIALOG: {
SuchAdr=0;
}return TRUE;
case WM_COMMAND: {
#define wNotifyCode GET_WM_COMMAND_CMD(wParam,lParam)
switch (LOWORD(wParam)) {
case 102: { //Listbox
if (wNotifyCode==LBN_SELCHANGE) EnableDlgItem(Wnd,1,TRUE);
}break;
case 103: { //Knopf "Suchen"
if (SuchAdr) { // Sucht noch?
KillTimer(Wnd,1);
SuchAdr=0;
}else{
SendDlgItemMessage(Wnd,102,LB_RESETCONTENT,0,0);
SuchAdr++;
SetTimer(Wnd,1,0,NULL);
}
InvalidateRect(GetDlgItem(Wnd,101),NULL,TRUE);
}break;
case 9: {
WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_ADRESSENSELEKTION);
}break;
case 1: { // OK-Knopf
char buf[4];
HWND w=GetDlgItem(Wnd,102); //Listbox
SendMessage(w,LB_GETTEXT,(WPARAM)SendMessage(w,LB_GETCURSEL,0,0),
(LPARAM)(LPSTR)buf);
EndDialog(Wnd,atoi(buf));
}break;
case 2: {
EndDialog(Wnd,0);
}break;
}/*switch*/
#undef wNotifyCode
}break;
case WM_TIMER: {
char buf[4];
KillTimer(Wnd,1); // Nicht verschachteln lassen
if (ISM_Abfrage(SuchAdr,NULL,0)) {
wsprintf(buf,"%u",SuchAdr);
SendDlgItemMessage(Wnd,102,LB_ADDSTRING,0,(LPARAM)(LPSTR)buf);
}
if (SuchAdr) { // wurde nicht zwischendurch gestoppt?
SuchAdr++;
InvalidateRect(GetDlgItem(Wnd,101),NULL,!SuchAdr);
if (SuchAdr) SetTimer(Wnd,1,0,NULL);
}
}break;
case WM_DRAWITEM: {
#define DIS ((LPDRAWITEMSTRUCT)lParam)
char buf[4];
HBRUSH br;
int r=DIS->rcItem.right;
DIS->rcItem.right=MulDiv(DIS->rcItem.right-DIS->rcItem.left,SuchAdr,255);
br=CreateSolidBrush(0xFF0000L);
FillRect(DIS->hDC,&DIS->rcItem,br);
DeleteObject(br);
DIS->rcItem.right=r;
if (SuchAdr) {
wsprintf(buf,"%u",SuchAdr);
DrawText(DIS->hDC,buf,-1,&DIS->rcItem,
DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE);
}
#undef DIS
}return TRUE;
}/*switch*/
return FALSE;
}
/*=====================================================*/
BOOL CALLBACK TransmitterDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG: {
WORD Baudrate;
UINT i;
SetWindowLong(Wnd,DWL_USER,lParam);
SetDlgItemInt(Wnd,1003,Get_ModulAdresse((BYTE)lParam),FALSE);
Baudrate=Get_Baudrate((BYTE)lParam);
for (i=1005; i<=1012; i++,Baudrate>>=1) {
if (Baudrate==300U) {
CheckDlgButton(Wnd,i,TRUE);
break;
}
}
}return TRUE;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case 9: {
WinHelp(Wnd,HelpFileName,HELP_CONTEXT,CM_KONFIGURATION_TRANSMITTER);
}break;
case 1: {
int br;
UINT a=GetDlgItemInt(Wnd,1003,NULL,FALSE);
if (!a || a>255) {
MBox(Wnd,0xA1A,MB_OK);
SetEditFocus(Wnd,1003);
return TRUE;
}
br=GetRadioCheck(Wnd,1005,1012);
if (br<0) {
MBox(Wnd,0xA1B,MB_OK);
return TRUE;
}
SetWaitCursor(Wnd,TRUE);
Set_ModulAdresse((BYTE)GetWindowLong(Wnd,DWL_USER),(BYTE)a);
Set_Baudrate((BYTE)a,(WORD)(300U<<br));
SetWaitCursor(Wnd,FALSE);
}nobreak;
case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
}/*switch*/
}break;
}/*switch*/
return FALSE;
}
/*=====================================================*/
BOOL CALLBACK IntervallDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam){
static const BYTE elapses[]={1,2,5,10,20,30,60,120,180}; //Sekunden
switch (Msg) { // Dieses Array entspricht String-Resource ab 0xA10!
case WM_INITDIALOG: {
#define IV ((LPINTERVALL)lParam)
UINT i;
char buf[32];
HWND w=GetDlgItem(Wnd,101); // List-Box füllen (aus String-Ressource)
SetDlgItemInt(Wnd,102,IV->count,FALSE);
for (i=0; i<elemof(elapses); i++) {
LoadString(hInstance,i+0xA10,buf,sizeof(buf));
SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPSTR)buf);
if (IV->elaps==elapses[i]) SendMessage(w,LB_SETCURSEL,i,0);
}
SetWindowLong(Wnd,DWL_USER,lParam); // Zeiger retten
#undef IV
}return TRUE;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case 9: {
WinHelp(Wnd,HelpFileName,HELP_CONTEXT,8000);
}break;
case 1: {
lParam=GetWindowLong(Wnd,DWL_USER);
#define IV ((LPINTERVALL)lParam)
IV->count=GetDlgItemInt(Wnd,102,NULL,FALSE);
if (IV->count<2 || IV->count>1500) {
MBox(Wnd,0xA19,MB_OK);
SetEditFocus(Wnd,102);
return TRUE;
}
IV->elaps=elapses[(int)SendDlgItemMessage(Wnd,101,LB_GETCURSEL,0,0)];
#undef IV
}nobreak;
case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
}/*switch*/
}break;
}/*switch*/
return FALSE;
}
/*=====================================================*/
BOOL CALLBACK PairInputDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
#define PI ((LPPAIRINPUT)lParam)
switch (Msg) {
case WM_INITDIALOG: {
char s[64];
SetWindowLong(Wnd,DWL_USER,lParam); // Zeiger retten
if (HIWORD(PI->title)) lstrcpyn(s,PI->title,sizeof(s));
else LoadString(hInstance,LOWORD(PI->title),s,sizeof(s));
SetWindowText(Wnd,s);
if (PI->v1) {
if (HIWORD(PI->v1)) lstrcpyn(s,PI->v1,sizeof(s));
else LoadString(hInstance,LOWORD(PI->v1),s,sizeof(s));
SetDlgItemText(Wnd,9001,s);
}
if (PI->v2) {
if (HIWORD(PI->v2)) lstrcpyn(s,PI->v2,sizeof(s));
else LoadString(hInstance,LOWORD(PI->v2),s,sizeof(s));
SetDlgItemText(Wnd,9002,s);
}
if (PI->komma>=0) {
SetDlgItemFloat(Wnd,9003,PI->komma,*PI->z1);
SetDlgItemFloat(Wnd,9004,PI->komma,*PI->z2);
}
}return TRUE;
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case 9: {
WinHelp(Wnd,HelpFileName,HELP_CONTEXT,3000);
}break;
case 1: {
float z;
lParam=GetWindowLong(Wnd,DWL_USER);
if (!GetDlgItemFloat(Wnd,9003,&z)) return FALSE;
if (!GetDlgItemFloat(Wnd,9004,PI->z2)) return FALSE;
*PI->z1=z; // beide Zahlen zugleich verändern!
if (PI->sort && z>*PI->z2) { // Umsortierung! z ist noch PI->z1
*PI->z1=*PI->z2;
*PI->z2=z;
}
}nobreak;
case 2: EndDialog(Wnd,(int)(LOWORD(wParam)));
}/*switch*/
}break;
}/*switch*/
return FALSE;
#undef PI
}
#ifdef __BORLANDC__
# pragma argsused
#endif
int _stdcall PairInput(HWND Wnd,LPCSTR pi,LPCSTR p1,LPCSTR p2,
float* p3,float* p4,BOOL p5,int p6) {
return DialogBoxParam(hInstance,MAKEINTRESOURCE(3000),Wnd,PairInputDlgProc,
(LPARAM)&pi);
}
/*=====================================================*/
#ifdef __BORLANDC__
# pragma argsused
#endif
BOOL CALLBACK AboutDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG: return TRUE;
case WM_COMMAND: EndDialog(Wnd,(int)(LOWORD(wParam)));
}
return FALSE;
}
Detected encoding: ANSI (CP1252) | 4
|
|