Source file: /~heha/ewa/Reluktanzmotor/cdesk-201007.zip/editx.cpp

#include "cdesk.h"
#include "editx.h"
#include "gdix.h"
#include <tchar.h>
#include <commctrl.h>

WNDPROC EditX::oldeditproc;
int EditX::oldwndextra;

/*static*/ BOOL EditX::init() {
// Superklassifiziert die Edit-Klasse
 WNDCLASSEX wc;
 wc.cbSize=sizeof wc;
 GetClassInfoEx(0,TEXT("Edit"),&wc);
 oldeditproc=wc.lpfnWndProc;
 oldwndextra=wc.cbWndExtra;
 wc.cbWndExtra+=sizeof(EditX*);
 wc.lpfnWndProc=wndproc;
 wc.lpszClassName=TEXT("EditX");
 return RegisterClassEx(&wc);
}

/*static*/ LRESULT CALLBACK EditX::wndproc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 EditX*self=(EditX*)GetWindowLongPtr(wnd,oldwndextra);
 if (!self) {
  self=new EditX(wnd);
  SetWindowLongPtr(wnd,oldwndextra,(LPARAM)self);
 }
 LRESULT ret=self->wndproc(msg,wParam,lParam);
 if (msg==WM_NCDESTROY) delete self;
 return ret;
}

HFONT EditX::makefont(HFONT f,BOOL redraw) const{
 Rect rc;
 GetClientRect(wnd,&rc);
 int h=rc.height();
 if (GetWindowStyle(wnd)&WS_BORDER) h-=GetSystemMetrics(SM_CYBORDER)<<1;	// Randbreite*2 subtrahieren
 if (GetWindowExStyle(wnd)&WS_EX_CLIENTEDGE) h-=2;
 LOGFONT lf;
 GetObject(f,sizeof lf,&lf);
 lf.lfHeight=h;
 lf.lfWidth=0;
 lf.lfOutPrecision=OUT_TT_ONLY_PRECIS;
 HFONT n=CreateFontIndirect(&lf);
 CallWindowProc(oldeditproc,wnd,WM_SETFONT,(WPARAM)n,redraw);
 return n;
}

LRESULT EditX::wndproc(UINT msg, WPARAM wParam, LPARAM lParam) {
 switch (msg) {
  case WM_CREATE: {
   CREATESTRUCT*cs=(CREATESTRUCT*)lParam;
   HWND hDlg=GetParent(wnd);
   if (cs->lpszName && *cs->lpszName) {	// Static-Elemente (im Dialog) davor und dahinter generieren; Platz muss sein
    HFONT f=GetWindowFont(hDlg);
    RECT rc;
    SetRect(&rc,0,0,40,8);	// 8 = nötige Höhe für Labels in Dialogeinheiten
    MapDialogRect(hDlg,&rc);
    int w=rc.right;		// Reservierbreite falls lins + rechts, Standard ist oben und unten
    int h=rc.bottom;
    GetWindowRect(wnd,&rc);
    rc.right-=rc.left;
    rc.bottom-=rc.top;
    ScreenToClient(hDlg,(POINT*)&rc);	// nur left+top
    TCHAR label[64],*unit;
    lstrcpyn(label,cs->lpszName,elemof(label));
    unit=_tcschr(label,'/');
    if (unit) *unit++=0;	// "Unit" ist alles hinter dem ersten Slash
    HWND hLabel=CreateWindowEx(0,TEXT("Static"),label,
      WS_CHILD|WS_VISIBLE/*|SS_LEFTNOWORDWRAP|SS_ENDELLIPSIS*/,
      rc.left,rc.top-GAP-h,rc.right,h,hDlg,(HMENU)-1,0,0);	// TODO: links und rechts noch nicht implementiert, erfordert Bestimmung der Stringlänge?
    SetWindowFont(hLabel,f,false);
    SetWindowPos(hLabel,GetPrevSibling(wnd),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
    if (unit) {
     HWND hUnit=CreateWindowEx(0,TEXT("Static"),unit,
       WS_CHILD|WS_VISIBLE|SS_RIGHT|SS_NOPREFIX,
       rc.left,rc.top+rc.bottom+GAP,rc.right,h,hDlg,(HMENU)-1,0,0);
     SetWindowFont(hUnit,f,false);
     SetWindowPos(hUnit,wnd,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
    }
    cs->lpszName=0;	// Editfenster leer erscheinen lassen
   }
   makefont((HFONT)GetStockObject(SYSTEM_FONT),false);
   if (!(cs->style&ES_READONLY)) {	// Kein UpDown bei ReadOnly
    DWORD sty=WS_CHILD|WS_BORDER|WS_VISIBLE|UDS_ALIGNRIGHT|UDS_ARROWKEYS|UDS_HOTTRACK;
    if (cs->style&ES_NUMBER) sty|=UDS_SETBUDDYINT;// Kein SetBuddyInt ohne ES_NUMBER (dann Gleitkomma)
    CreateUpDownControl(sty,0,0,0,0,hDlg,-1,0,wnd,100,0,0);
   }
  }break;
  case WM_SETFONT:if (wParam){
   Font of(wnd);	// Rekursion (unkritisch)
   makefont((HFONT)wParam,LOWORD(lParam));
   // of wird vom Destruktor zerstört
  }return TRUE;		// nicht durchleiten!
  case WM_DESTROY: {
   Font of(wnd);	// Destruktor macht DeleteFont
  }break;
 }
 return CallWindowProc(oldeditproc,wnd,msg,wParam,lParam);
}

bool EditX::getDouble(double&val) const {
 TCHAR s[32];
 GetWindowText(wnd,s,elemof(s));
 TCHAR*p=_tcschr(s,',');
 if (p) *p='.';
 double v;
 int n,k=_stscanf(s,TEXT("%lf%n"),&v,&n);	// TODO: Mit Einheitenvorsatz, INF/NAN
 if (!k) return false;		// Inkorrekt: Keine Ziffer oder Vorzeichen am Amfang
 if (s[n]) return false;	// Buchstaben danach
 if (val==v) return false;	// nichts zu ändern
 val=v; return true;		// in Ordnung
}

bool EditX::setDouble(const double&val) {
 TCHAR s[32];
 _sntprintf(s,elemof(s),TEXT("%.*f"),nk,val);
 TCHAR*p=_tcschr(s,'.');
 if (p) *p=::sDecimal[0];
 SetWindowText(wnd,s);
 return true;
}
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded