#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <tchar.h>
#include <shlwapi.h>
#include <shlobj.h>
// Langweile h#s-Defines. Siehe http://www.tu-chemnitz.de/~heha/hs_freeware/mein_msvc.htm
#define T(x) TEXT(x)
#define nobreak
#define elemof(x) (sizeof(x)/sizeof(*(x)))
// msvcrt-light.lib für Visual Studio 2005 sowie Gleitkommaverwendung zugänglich machen
extern "C" _CRTIMP void _cdecl __getmainargs(int*,char***,char***,void*,void*);
extern "C" void* _imp___ftol;
extern "C" _declspec(naked) int _cdecl _ftol2_sse() {_asm jmp [_imp___ftol]}
extern "C" int _fltused; int _fltused;
extern "C" _CRTIMP FILE _iob[3];
#undef stdin
#undef stdout
#undef stderr
#define stdin (_iob+0)
#define stdout (_iob+1)
#define stderr (_iob+2)
#define ghInstance (HINSTANCE)0x400000
HWND ghEdit;
void InitStruct(LPVOID p, UINT len) {
ZeroMemory(p,len);
*(LPDWORD)p=len;
}
/* Die Quelldatei besteht aus einem Mix aus Binär- und ASCII-Daten.
* Die gemessenen Positionen ("Sample no" Werte) liegen in Binärform
* als Gleitkommazahlen (Einheit "mm") vor.
* Diese Konvertierung kopiert die Quell- zur Zieldatei, aber wandelt
* die binären Positionsangaben in ASCII-Abweichungen um.
* (Einheit "mm" mit 4 Nachkommastellen, also 0,1 µm, die Auflösung des
* Laserinterferometers)
* Diese Funktion liefert "false" bei irgendeinem Fehler; die
* Zieldatei sollte daraufhin gelöscht werden.
*/
bool Konvertierung(LPCTSTR QuellName, LPCTSTR ZielName) {
FILE *in,*out;
bool ret=false; // pessimistisch
// Die Dateien müssen "binär" verarbeitet werden, damit nicht beim fread()
// die 0D-0A -> 0A-Konvertierung zuschlägt und die Daten zerstört.
in=_tfopen(QuellName,T("rb"));
if (in) {
out=_tfopen(ZielName,T("wb"));
if (out) {
char line[1024];
float fSamples,fInterval=0;
int iSamples=0;
int iFlag=0;
while (fgets(line,sizeof(line),in)) { // Zeilen lesen (mit "\r\n" am Ende)
fputs(line,out); // Echo
if (sscanf(line,"Sample no :%f",&fSamples)==1) iSamples=(int)fSamples;
sscanf(line,"Trigger interval :%f",&fInterval);
sscanf(line,"Flags: %d",&iFlag);
if (strcmp(line,"Run Target Data:\r\n")==0) {
// Ab hier kommt der Binärkram
if (!iSamples) break; // Fehler: keine Samplezahl im Kopfbereich
retry:
switch (iFlag) {
case 2: { // RTX mit DOUBLE-Werten
// Notwendigen Speicher anfordern
double *adValues = new double[iSamples];
if (!adValues) break;
// Binärdaten in einem Stück lesen
if (fread(adValues,sizeof(double),iSamples,in) != iSamples) break;
// ASCII-Daten zeilenweise ausgeben
for (int i=0; i<iSamples; i++) { // Zeilennummer, Position oder Zeitpunkt, Abweichung
fprintf(out,"%d\t%.4f\t%.4f\r\n",i,fInterval*i,adValues[i]);
}
delete[] adValues;
}break;
case 3: { // RTD mit SINGLE-Werten
// Notwendigen Speicher anfordern
float *afValues = new float[iSamples];
if (!afValues) break;
// Binärdaten in einem Stück lesen
if (fread(afValues,sizeof(float),iSamples,in) != iSamples) break;
// ASCII-Daten zeilenweise ausgeben
for (int i=0; i<iSamples; i++) { // Zeilennummer, Messwert, Abweichung
fprintf(out,"%d\t%.4f\t%.4f\r\n",i,afValues[i],afValues[i]-fInterval*i);
}
delete[] afValues;
}break;
default: { // raten anhand Datei-Restgröße (140107)
DWORD p=ftell(in);
fseek(in,0,SEEK_END);
DWORD q=ftell(in)-p;
fseek(in,p,SEEK_SET);
if (q>=iSamples*sizeof(double)) {iFlag=2; goto retry;}
if (q>=iSamples*sizeof(float)) {iFlag=3; goto retry;}
}goto raus;
}
if (!fflush(out)) ret=true; // jetzt kann nichts mehr passieren
}
}
raus:
fclose(out);
}
fclose(in);
}
return ret;
}
// Nachricht in Editfenster ausgeben (so umständlich wirklich nötig? Scheint so…)
void _cdecl WriteMsg(LPCTSTR Line,...) {
DWORD SelStart,SelEnd,BufLen;
LPTSTR buf;
BufLen=GetWindowTextLength(ghEdit)+1024;
buf=new TCHAR[BufLen];
BufLen=GetWindowText(ghEdit,buf,BufLen); // Text holen
BufLen+=wvsprintf(buf+BufLen,Line,(va_list)(&Line+1)); // Text anhängen
lstrcpy(buf+BufLen,T("\r\n")); // CRLF anhängen
SendMessage(ghEdit,EM_GETSEL,(WPARAM)&SelStart,(LPARAM)&SelEnd); // retten
SetWindowText(ghEdit,buf); // Text setzen
delete[] buf;
Edit_SetSel(ghEdit,SelStart,SelEnd); // Selektion restaurieren
}
// Kopiert eine Datei (*.RT[DX]) durch Anhängen von ".TXT" am Dateinamen
// ins Binärformat und gibt Kommentare per WriteMsg()
void ProcessFile(LPCTSTR QuellName,FILETIME*pQuellTime) {
TCHAR ZielName[MAX_PATH];
WIN32_FILE_ATTRIBUTE_DATA wfads,wfadd; // Datei-Datum Quelle und Ziel
// Quell-Dateidatum ermitteln
if (pQuellTime) wfads.ftLastWriteTime=*pQuellTime;
else GetFileAttributesEx(QuellName,GetFileExInfoStandard,&wfads);
// Ziel-Dateiname ermitteln
lstrcpyn(ZielName,QuellName,elemof(ZielName));
StrCatBuff(ZielName,T(".txt"),elemof(ZielName));
// Ziel-Datei auf Existenz prüfen und Datum ermitteln sowie vergleichen
if (GetFileAttributesEx(ZielName,GetFileExInfoStandard,&wfadd)
&& CompareFileTime(&wfads.ftLastWriteTime,&wfadd.ftLastWriteTime)<=0) {
WriteMsg(T("Überspringe Datei %s, Zieldatei bereits vorhanden und neuer, OK"),QuellName);
}else{
if (Konvertierung(QuellName,ZielName)) {
WriteMsg(T("Datei %s konvertiert nach %s: OK"),QuellName,ZielName);
}else{
WriteMsg(T("Konvertierung Datei %s fehlgeschlagen!"),QuellName);
DeleteFile(ZielName); // Eventuelles Rudiment löschen
}
}
}
// In akt. Verzeichnis alle *.RTD in *.RTD.TXT wandeln, sofern letztere
// nicht schon in aktuellerer Version vorhanden sind (wie make)
// OHNE Rekursion in Unterverzeichnisse
void ProcessCurrentDirectory(void) {
HANDLE fh;
WIN32_FIND_DATA wfd;
bool found=false;
fh=FindFirstFile(T("*.RTD"),&wfd);
if (fh) {
found=true;
do{
ProcessFile(wfd.cFileName,&wfd.ftLastWriteTime);
}while (FindNextFile(fh,&wfd));
FindClose(fh);
}
fh=FindFirstFile(T("*.RTX"),&wfd);
if (fh) {
found=true;
do{
ProcessFile(wfd.cFileName,&wfd.ftLastWriteTime);
}while (FindNextFile(fh,&wfd));
FindClose(fh);
}
if (!found) WriteMsg(T("Keine Renishaw .RT[DX]-Datei im Verzeichnis!"));
}
int CALLBACK BrowseCallbackProc(HWND Wnd,UINT Msg,LPARAM,LPARAM) {
switch (Msg) {
case BFFM_INITIALIZED: {
WCHAR CurDir[MAX_PATH];
GetCurrentDirectoryW(elemof(CurDir),CurDir);
SendMessage(Wnd,BFFM_SETSELECTION,TRUE,(LPARAM)CurDir);
}break;
}
return 0;
}
bool ChooseDirectory(HWND Parent, LPTSTR DirName) {
BROWSEINFO bi={Parent,NULL,NULL,NULL,
BIF_NEWDIALOGSTYLE|BIF_NONEWFOLDERBUTTON|BIF_RETURNONLYFSDIRS,
BrowseCallbackProc,0,0};
LPITEMIDLIST pidl;
CoInitialize(NULL);
pidl=SHBrowseForFolder(&bi);
if (!pidl) return false;
SHGetPathFromIDList(pidl,DirName);
CoTaskMemFree(pidl);
return true;
}
LRESULT CALLBACK MainWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_CREATE: {
ghEdit=CreateWindowEx(0,T("EDIT"),NULL,
WS_CHILD|WS_VISIBLE/*|ES_READONLY*/|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_WANTRETURN|ES_NOHIDESEL|WS_VSCROLL,
0,0,0,0,
Wnd,(HMENU)1,ghInstance,NULL);
WriteMsg(T("Datei oder Verzeichnis zwecks Konvertierung auswählen!"));
WriteMsg(T("Log-Anzeige..."));
}break;
case WM_SIZE: {
SetWindowPos(ghEdit,0,0,0,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam),SWP_NOMOVE|SWP_NOZORDER);
}break;
case WM_COMMAND: switch (LOWORD(wParam)){
case 101: { // Datei öffnen
TCHAR *Files=new TCHAR[MAX_PATH*300],*p;
Files[0]=0;
OPENFILENAME ofn;
InitStruct(&ofn,sizeof(ofn));
ofn.hwndOwner=Wnd;
ofn.lpstrFile=Files;
ofn.nMaxFile=MAX_PATH*300;
ofn.lpstrFilter=T("Renishaw-RT[DX]-Dateien\0*.RTD;*.RTX\0");
ofn.Flags=OFN_ALLOWMULTISELECT|OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) {
if (SetCurrentDirectory(Files)) { // mehrere Dateinamen angegeben...
p=Files+lstrlen(Files)+1; // p = erster Dateiname
do{
ProcessFile(p,NULL);
p+=lstrlen(p)+1; // nächster Dateiname
}while(*p);
}else{
ProcessFile(Files,NULL); // eine Datei konvertieren
}
}
delete[] Files;
}break;
case 102: {
TCHAR DirName[MAX_PATH];
if (ChooseDirectory(Wnd,DirName)){
SetCurrentDirectory(DirName);
ProcessCurrentDirectory();
}
}break;
case 109: SendMessage(Wnd,WM_CLOSE,0,0); break; // beenden
case 199: MessageBox(Wnd,T("RT[DX]-Konvertierer TU Chemnitz WZM"),T("Über gRTD"),0);
}break;
case WM_DESTROY: {
PostQuitMessage(0);
}break;
}
return DefWindowProc(Wnd,Msg,wParam,lParam);
}
void CALLBACK WinMainCRTStartup() {
WNDCLASS wc={
CS_HREDRAW|CS_VREDRAW,
MainWndProc,
0,0,
ghInstance,
LoadIcon(0,IDI_APPLICATION),
LoadCursor(0,IDC_ARROW),
0,
MAKEINTRESOURCE(1),
T("gRTD")};
RegisterClass(&wc);
HWND Wnd=CreateWindow(T("gRTD"),T("gRTD"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,ghInstance,NULL);
ShowWindow(Wnd,SW_SHOWDEFAULT);
MSG Msg;
while (GetMessage(&Msg,0,0,0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
ExitProcess((UINT)Msg.wParam);
}
Detected encoding: ANSI (CP1252) | 4
|
|