#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;
}
Vorgefundene Kodierung: ANSI (CP1252) | 4
|
|