/** Editor ED - Modul UT: Utensilien **/
#include "top.h"
#include <windows.h>
#include <tchar.h>
#include <stdarg.h>
#define SWAPLONG(l) (((l) >> 16) | ((l) & 0x00FF00) | (((l) & 0x0000FF) << 16))
/** Function: Erweiterte MessageBox-Funktion **/
int ut_messageBoxExt(HWND hWnd, const TCHAR *msg, const TCHAR *title, unsigned type, ...)
{
va_list varg;
TCHAR s[256];
va_start(varg, type); // Muss auf letztes Fixarg zeigen
wvsprintf(s, msg, varg);
va_end(varg); // LCC-Warn. ignorieren
s[sizeof s / sizeof(TCHAR) - 1] = TEXT('\0');
return MessageBox(hWnd, s, title, type);
}
/** Function: Kopiere Text aus EDIT-Control in Puffer **/
TCHAR *ut_getEditText(HWND hWinEdit, int *len)
{
int bufLen;
TCHAR *buf;
if (len)
*len = 0;
if ((bufLen=GetWindowTextLength(hWinEdit)) == 0)
return NULL;
if ((buf=(TCHAR*)GlobalAlloc(GMEM_FIXED, (bufLen+1)*sizeof(TCHAR))) == NULL)
return NULL; // Leider muss erst _gesamter_ Text kopiert werden, um Markierung zu erhalten
GetWindowText(hWinEdit, buf, bufLen+1); // Selbst wenn Text aus Datei mit SetWindowTextA() auf
if (len) // ANSI fixiert eingelesen wurde, befuellt GetWindowText() unter UNICODE (GetWindowTextW)
*len = bufLen; // Puffer mit Unicode-Text - daher funktionieren Suchroutinen!
return buf;
}
/** Function: Kopiere markierten Text aus EDIT-Control in Puffer **/
TCHAR *ut_getEditSel(HWND hWinEdit, int *len)
{
int sos, eos, selLen;
TCHAR *buf, *sel;
if (len)
*len = 0;
SendMessage(hWinEdit, EM_GETSEL, (WPARAM)&sos, (LPARAM)&eos);
if ((selLen=eos-sos) == 0)
return NULL;
if ((buf=ut_getEditText(hWinEdit, NULL)) == NULL)
return NULL;
if ((sel=(TCHAR*)GlobalAlloc(GMEM_FIXED, (selLen+1)*sizeof(TCHAR))) == NULL) {
GlobalFree(buf); return NULL; }
lstrcpyn(sel, buf+sos, selLen+1); // Unterschied zu strncpy: lstrcpyn kopiert nur n Zeichen,
GlobalFree(buf); // wenn n+1 angegeben, um Null mitanzuhaengen!
if (len)
*len = selLen;
return sel;
}
/** Function: Wandele Zahl in Zeichenkette **/
TCHAR *ut_uLong2Str(unsigned long l, unsigned int radix)
{
static TCHAR s[13]; // Muss 13 sein, da printf Zahlen nicht trunkieren kann (Strings schon)!
s[0] = 0;
if (radix == 16)
wsprintf(s, TEXT("%06lX"), l); // _ultot(l,s,16) erlaubt leider keine Formatbreite
else if (radix == 10)
wsprintf(s, TEXT("%ld"), l);
return s;
}
#ifdef BUILD_UC
/** Function: Wandele BGR-Zahl in RGB-Zeichenkette **/
TCHAR *ut_revRGBStr(unsigned long l)
{
return ut_uLong2Str(SWAPLONG(l),16); // BGR -> RGB
}
/** Function: Wandele RGB-Zeichenkette in BGR-Zahl **/
unsigned long ut_revRGBVal(TCHAR *s)
{
unsigned long l = _tcstoul(s, NULL, 16); // Es gibt kein lstrtoul() in Windows
return SWAPLONG(l); // RGB -> BGR
}
#endif
/** Function: Ermittele Kommandozeilenargumente **/
BOOL ut_getArg(TCHAR s[], TCHAR arg[])
{
static TCHAR *psave;
TCHAR stop, *p;
/* Initialisiere */
if (!arg) {
if (!s)
return FALSE;
psave = s;
return FALSE;
}
if (!psave) // Von nun an MUSS psave ein gueltiger Zeiger sein!
return FALSE;
/* Fahre an letzter Suchposition fort */
*arg = TEXT('\0');
p = psave;
/* Ueberspringe fuehrende Leerzeichen */
while (*p == TEXT(' '))
++p;
if (!*p) {
psave = NULL; return FALSE; }
/* Ermittele Endezeichen */
if (*p == TEXT('"')) {
stop = TEXT('"'); ++p; }
else
stop = TEXT(' ');
/* Merke Wortbeginn */
psave = p;
/* Laufe bis Endezeichen */
do ++p; while (*p && *p != stop);
/* Kopiere Zeichenkette */
lstrcpyn(arg, psave, (int)(p-psave+1)); // Anders als strncpy kopiert lstrcpyn nur n Zeichen,
if (!*p) // wenn n+1 angegeben, um 0 mitanzuhaengen!
psave = p;
else
psave = p + 1;
return TRUE;
}
/** Function: Ergibt TRUE, wenn path als Ordner existiert **/
BOOL ut_dirExists(const TCHAR path[])
{
DWORD h;
if (!path || path[0] == '\0')
return FALSE;
h = GetFileAttributes(path);
if (h == 0xFFFFFFFF)
return FALSE;
return (BOOL) (h & FILE_ATTRIBUTE_DIRECTORY);
}
/** Function: Ergibt TRUE, wenn path als Datei existiert **/
BOOL ut_fileExists(const TCHAR path[])
{
DWORD h;
if (!path || path[0] == '\0')
return FALSE;
h = GetFileAttributes(path);
if (h == 0xFFFFFFFF)
return FALSE;
return (BOOL) !(h & FILE_ATTRIBUTE_DIRECTORY);
/* Oder:
WIN32_FIND_DATA data;
HANDLE handle = FindFirstFile(dirName,&data);
if (handle != INVALID_HANDLE_VALUE) {
FindClose(handle);
return true;
}
return false;
*/
}
#ifdef BUILD_FR
/** Function: Suche Zeichenkette in Zeichenkette ohne Beachtung von Gross- und Kleinschreibung **/
static TCHAR *_ut_strstri(const TCHAR *str, const TCHAR *pat)
{
// Rev. History:
// 02/03/94 Fred Cole: Original
// 07/04/95 Bob Stout: ANSI-fy
// 16/07/97 Greg Thayer: Optimized
// 09/01/03 Bob Stout: Bug fix (lines 40-41) per Fred Bulback
// 12/09/08 As Dala: Modified
// CharLower() wandelt sowohl Zeichenketten als auch Zeichen um; da aber Funktion als
// LPTSTR CharLower(LPTSTR lpsz) deklariert ist, muessen wir Funktionsergebnis fuer Zeichen in
// TCHAR* umwandeln, damit Kompiler Ruhe gibt. Wenn wir nur CharLower-Ergebnisse vergleichen,
// kann allerdings Umwandlung des Funktionsergebnisses entfallen. Ausserdem muessen wir
// Suchzeichen in WORD umwandeln, damit keine neg. Vorzeichenerw. passiert ('ü' -> int -4).
// Ignoriere LCC-Warnungen: CharLower gibt 32bit zurück, falls Parameter ein Zeichen war.
TCHAR *s0, *s, p0, *p;
/* Init */
s0 = (TCHAR *) str;
p0 = (TCHAR) CharLower((TCHAR*)(WORD)(*pat)); // Ignoriere Warn.
while (*s0) {
/* pat[0] in str enthalten? */
while ((TCHAR) CharLower((TCHAR*)(WORD)*s0) != p0) // Ignoriere Warn.
if (!*++s0)
return NULL;
s = s0;
p = (TCHAR *) pat;
/* Ja. pat[1..n] in str enthalten? */
do {
++s;
++p;
if (!*p) // Falls Ende des Suchmusters erreicht, ist Fund bestaetigt
return (TCHAR *) s0;
} while (CharLower((TCHAR*)(WORD)*s) == CharLower((TCHAR*)(WORD)*p));
s0++;
}
return NULL;
}
/** Function: Suche Zeichenkette in Zeichenkette **/
TCHAR *ut_strstr(const TCHAR *str, const TCHAR *pat, BOOL matchCase, BOOL wholeWord)
{
TCHAR *h = (TCHAR*)str;
UINT patlen = lstrlen(pat);
if (str == NULL || pat == NULL)
return NULL;
while ((h = matchCase ? _tcsstr(h,pat) : _ut_strstri(h,pat)) != NULL) {
if (!wholeWord || ((h==str || !IsCharAlpha(*(h-1))) && !IsCharAlpha(*(h+patlen))))
break;
++h;
}
return h;
}
#endif