/*
- * Copyright 2003 Martin Fuchs
+ * Copyright 2003, 2004 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <windowsx.h> // for SelectBrush(), ListBox_SetSel(), SubclassWindow(), ...
#include <commctrl.h>
+#ifndef _MSC_VER
+#include <objbase.h>
+#endif
+#include <oleauto.h> // for VARIANT
+
#include <malloc.h> // for alloca()
#include <assert.h>
#include <stdlib.h> // for _MAX_DIR, ...
#define _MAX_PATH 260
#endif
+#define W_VER_NT 0 // constant for HIWORD(GetVersion())>>14
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define for if (0) {} else for
+
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+
+#define BUFFER_LEN 2048
+
+
+extern void _log_(LPCTSTR txt);
+
+#define LOG(txt) _log_(txt)
+
+
+#ifdef _MSC_VER
+#define LONGLONGARG TEXT("I64")
+#else
+#define LONGLONGARG TEXT("L")
+#endif
+
+
+#ifndef _tcsrchr
+#ifdef UNICODE
+#define _tcsrchr wcsrchr
+#else
+#define _tcsrchr strrchr
+#endif
+#endif
+
+#ifndef _stprintf
+#ifdef UNICODE
+#define _stprintf wcsprintf
+#else
+#define _stprintf sprintf
+#endif
+#endif
+
+#define U2A(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, -1, d, l, NULL, NULL)
+#define U2nA(s, d, l) WideCharToMultiByte(CP_ACP, 0, s, l, d, l, NULL, NULL)
+#define A2U(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, -1, d, l)
+#define A2nU(s, d, l) MultiByteToWideChar(CP_ACP, 0, s, l, d, l)
+
+
+#ifdef __WINE__
+#ifdef UNICODE
+extern void _wsplitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
+#else
+extern void _splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext);
+#endif
+#define _tcsnicmp strncasecmp
+#define _tcsicoll strcasecmp
+#endif
+
+#ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
+#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040
+#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#endif
+
+
+#define SetDlgCtrlID(hwnd, id) SetWindowLong(hwnd, GWL_ID, id)
+#define SetWindowStyle(hwnd, val) (DWORD)SetWindowLong(hwnd, GWL_STYLE, val)
+#define SetWindowExStyle(h, val) (DWORD)SetWindowLong(hwnd, GWL_EXSTYLE, val)
+#define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
+
+
+ // center window in respect to its parent window
+extern void CenterWindow(HWND hwnd);
+
+ // move window into visibility
+extern void MoveVisible(HWND hwnd);
+
+ // display error message
+extern void display_error(HWND hwnd, DWORD error);
+
+ // convert time_t to WIN32 FILETIME
+extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime);
+
+ // search for windows of a specific classname
+extern int find_window_class(LPCTSTR classname);
+
+ // create a directory with all missing parent directories
+BOOL RecursiveCreateDirectory(LPCTSTR path_in);
+
+ // read DWORD value from registry
+DWORD RegGetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD def);
+
+ // write DWORD value to registry
+BOOL RegSetDWORDValue(HKEY root, LPCTSTR path, LPCTSTR valueName, DWORD value);
+
+ // test for existing directory
+BOOL exists_path(LPCTSTR path);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#ifdef __cplusplus
#include <iostream>
using namespace std;
+ // containers
+#include <map>
+#include <set>
+#include <list>
+#include <stack>
+#include <vector>
+
+
#if _MSC_VER>=1300 // VS.Net
#define _NO_COMUTIL //@@
#endif
#endif // _MSC_VER && !_NO_COMUTIL
-#define for if (0) {} else for
+ // launch a program or document file
+extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow=SW_SHOWNORMAL, LPCTSTR parameters=NULL);
+#ifdef UNICODE
+extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow=SW_SHOWNORMAL, LPCSTR parameters=NULL);
+#else
+#define launch_fileA launch_file
+#endif
+ // call an DLL export like rundll32
+extern BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow);
-#define BUFFER_LEN 1024
+ // launch control panel applet
+extern BOOL launch_cpanel(HWND hwnd, LPCTSTR applet);
/// initialization of windows common controls
struct HiddenWindow : public WindowHandle
{
HiddenWindow(HWND hwnd)
- : WindowHandle(hwnd)
+ : WindowHandle(IsWindowVisible(hwnd)? hwnd: 0)
{
- SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
+ if (_hwnd)
+ SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
}
~HiddenWindow()
{
- SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
+ if (_hwnd)
+ SetWindowPos(_hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
}
};
struct Thread
{
Thread()
- : _alive(false)
+ : _alive(false),
+ _destroy(false)
{
_hThread = INVALID_HANDLE_VALUE;
+ _evtFinish = CreateEvent(NULL, TRUE, FALSE, NULL);
}
virtual ~Thread()
{
Stop();
+ CloseHandle(_evtFinish);
CloseHandle(_hThread);
+
+ if (_destroy)
+ delete this;
}
void Start()
void Stop()
{
+ SetEvent(_evtFinish);
+
if (_alive) {
{
Lock lock(_crit_sect);
static DWORD WINAPI ThreadProc(void* para);
HANDLE _hThread;
+ HANDLE _evtFinish;
bool _alive;
+ bool _destroy;
};
COLORREF _old_color;
};
- /// TextColor locally sets the background mode for drawing.
+ /// BkMode locally sets the background mode for drawing.
struct BkMode
{
BkMode(HDC hdc, int bkmode)
COLORREF _old_bkmode;
};
- /// TextColor locally selects a font for drawing.
+ /// FontSelection locally selects a font for drawing.
struct FontSelection
{
FontSelection(HDC hdc, HFONT hFont)
HFONT _old_hFont;
};
- /// TextColor locally selects a bitmap into a device context.
+ /// BitmapSelection locally selects a bitmap into a device context.
struct BitmapSelection
{
BitmapSelection(HDC hdc, HBITMAP hBmp)
HBITMAP _old_hBmp;
};
+ /// BrushSelection locally selects a brush into a device context.
+struct BrushSelection
+{
+ BrushSelection(HDC hdc, HBRUSH hBrush)
+ : _hdc(hdc), _old_hBrush(SelectBrush(hdc, hBrush)) {}
+
+ ~BrushSelection() {SelectBrush(_hdc, _old_hBrush);}
+
+protected:
+ HDC _hdc;
+ HBRUSH _old_hBrush;
+};
+
+
+ /// Popup Menus
+struct PopupMenu
+{
+ PopupMenu()
+ : _hmenu(CreatePopupMenu())
+ {
+ }
+
+ PopupMenu(UINT nid);
+
+ operator HMENU() {return _hmenu;}
+
+ void Append(UINT id, LPCTSTR str, UINT flags=MF_STRING)
+ {
+ AppendMenu(_hmenu, flags, id, str);
+ }
+
+ int TrackPopupMenu(HWND hwnd, const POINT& pt, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON, LPTPMPARAMS tpm=NULL) {
+ return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, tpm);
+ }
+
+ int PopupContextMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
+ POINT pt; POINTSTOPOINT(pt, pos);
+ return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
+ }
+
+ int TrackPopupMenu(HWND hwnd, POINTS pos, UINT flags=TPM_LEFTBUTTON|TPM_RIGHTBUTTON) {
+ POINT pt; POINTSTOPOINT(pt, pos);
+ ClientToScreen(hwnd, &pt);
+ return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
+ }
+
+ int TrackPopupMenuAtCursor(HWND hwnd, UINT flags=TPM_LEFTBUTTON) {
+ POINT pt; GetCursorPos(&pt);
+ return TrackPopupMenuEx(_hmenu, flags, pt.x, pt.y, hwnd, NULL);
+ }
+
+ int TrackPopupMenuAtPos(HWND hwnd, DWORD pos, UINT flags=TPM_LEFTBUTTON) {
+ return TrackPopupMenuEx(_hmenu, flags, GET_X_LPARAM(pos), GET_Y_LPARAM(pos), hwnd, NULL);
+ }
+
+protected:
+ HMENU _hmenu;
+};
+
+
+struct Variant : public VARIANT
+{
+ Variant() {VariantInit(this);}
+ Variant(const VARIANT& var);
+ Variant(const VARIANT* var);
+ ~Variant();
+
+ operator long() const;
+ operator bool() const;
+ operator VARIANT_BOOL() const;
+ operator IDispatch*() const;
+};
+
+
+struct BStr
+{
+ BStr()
+ {
+ _p = NULL;
+ }
+
+ BStr(const BSTR s)
+ {
+ _p = SysAllocString(s);
+ }
+
+ BStr(LPCSTR s)
+ {
+ WCHAR b[BUFFER_LEN];
+
+ if (s)
+ _p = SysAllocStringLen(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);
+ else
+ _p = NULL;
+ }
+
+ BStr(LPCWSTR s)
+ {
+ _p = SysAllocString(s);
+ }
+
+ BStr(const VARIANT& var)
+ : _p(NULL)
+ {
+ assign(var);
+ }
+
+ ~BStr()
+ {
+ SysFreeString(_p);
+ }
+
+ void assign(BSTR s);
+ void assign(const VARIANT& var);
+
+ operator BSTR() const
+ {
+ return _p? _p: (BSTR)L"";
+ }
+
+ int length() const
+ {
+ return _p? wcslen(_p): 0;
+ }
+
+protected:
+ BSTR _p;
+};
+
- /// string class for convenience
+ /// string class for TCHAR strings
struct String
#ifdef UNICODE
: public wstring
#endif
String() {}
- String(LPCTSTR s) : super(s) {}
+
+ String(LPCTSTR s) {if (s) super::assign(s);}
+ String(LPCTSTR s, int l) : super(s, l) {}
+
String(const super& other) : super(other) {}
String(const String& other) : super(other) {}
#ifdef UNICODE
String(LPCSTR s) {assign(s);}
+ String(LPCSTR s, int l) {assign(s, l);}
+ String(const string& other) {assign(other.c_str());}
String& operator=(LPCSTR s) {assign(s); return *this;}
- void assign(LPCSTR s) {TCHAR b[BUFFER_LEN]; MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN); super::assign(b);}
+ void assign(LPCSTR s) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, -1, b, BUFFER_LEN)-1);} else erase();}
+ void assign(LPCSTR s, int l) {if (s) {TCHAR b[BUFFER_LEN]; super::assign(b, MultiByteToWideChar(CP_ACP, 0, s, l, b, BUFFER_LEN));} else erase();}
+ void assign(const BStr& s) {int l = s.length(); super::assign(s, l);}
#else
String(LPCWSTR s) {assign(s);}
+ String(LPCWSTR s, int l) {assign(s, l);}
+ String(const wstring& other) {assign(other.c_str());}
String& operator=(LPCWSTR s) {assign(s); return *this;}
- void assign(LPCWSTR s) {char b[BUFFER_LEN]; WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0); super::assign(b);}
+ void assign(LPCWSTR s) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, -1, b, BUFFER_LEN, 0, 0)-1);} else erase();}
+ void assign(LPCWSTR s, int l) {if (s) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
+ void assign(const BStr& s) {int l = s.length(); if (l) {char b[BUFFER_LEN]; super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, BUFFER_LEN, 0, 0));} else erase();}
#endif
+ String(const BStr& s) {assign(s);}
+ String& operator=(const BStr& s) {assign(s); return *this;}
- String& operator=(LPCTSTR s) {super::assign(s); return *this;}
+ String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
String& operator=(const super& s) {super::assign(s); return *this;}
+ void assign(LPCTSTR s) {super::assign(s);}
+ void assign(LPCTSTR s, int l) {super::assign(s, l);}
operator LPCTSTR() const {return c_str();}
+
+#ifdef UNICODE
+ operator string() const {char b[BUFFER_LEN]; return string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN, 0, 0)-1);}
+#else
+ operator wstring() const {WCHAR b[BUFFER_LEN]; return wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), -1, b, BUFFER_LEN)-1);}
+#endif
+
+ String& printf(LPCTSTR fmt, ...)
+ {
+ va_list l;
+ TCHAR b[BUFFER_LEN];
+
+ va_start(l, fmt);
+ super::assign(b, _vstprintf(b, fmt, l));
+ va_end(l);
+
+ return *this;
+ }
+
+ String& vprintf(LPCTSTR fmt, va_list l)
+ {
+ TCHAR b[BUFFER_LEN];
+
+ super::assign(b, _vstprintf(b, fmt, l));
+
+ return *this;
+ }
+
+ String& appendf(LPCTSTR fmt, ...)
+ {
+ va_list l;
+ TCHAR b[BUFFER_LEN];
+
+ va_start(l, fmt);
+ super::append(b, _vstprintf(b, fmt, l));
+ va_end(l);
+
+ return *this;
+ }
+
+ String& vappendf(LPCTSTR fmt, va_list l)
+ {
+ TCHAR b[BUFFER_LEN];
+
+ super::append(b, _vstprintf(b, fmt, l));
+
+ return *this;
+ }
+};
+
+#define _STRING_DEFINED
+
+
+struct FmtString : public String
+{
+ FmtString(LPCTSTR fmt, ...)
+ {
+ va_list l;
+
+ va_start(l, fmt);
+ vprintf(fmt, l);
+ va_end(l);
+ }
};
+#ifdef UNICODE
+
+struct ANS
+{
+ ANS(LPCWSTR s)
+ {
+ int l = wcslen(s) + 1;
+ _str = (LPSTR) malloc(2*l);
+
+ if (WideCharToMultiByte(CP_ACP, 0, s, -1, _str, 2*l, 0, 0) <= 0)
+ *_str = '\0';
+ }
+
+ ~ANS()
+ {
+ free(_str);
+ }
+
+ operator LPCSTR() {return _str;}
+
+protected:
+ LPSTR _str;
+};
+
+#define UNC(x) ((LPCWSTR)(x))
+
+#else
+
+#define ANS(x) ((LPCSTR)(x))
+
+struct UNC
+{
+ UNC(LPCSTR s)
+ {
+ int l = strlen(s) + 1;
+ _str = (LPWSTR) malloc(2*l);
+
+ if (MultiByteToWideChar(CP_ACP, 0, s, -1, _str, l) <= 0)
+ *_str = '\0';
+ }
+
+ ~UNC()
+ {
+ free(_str);
+ }
+
+ operator LPCWSTR() {return _str;}
+
+protected:
+ LPWSTR _str;
+};
+
+#endif
+
+
+ // determine windows version string
+String get_windows_version_str();
+
+
/// link dynamicly to functions by using GetModuleHandle() and GetProcAddress()
template<typename FCT> struct DynamicFct
{
struct Context
{
- Context(LPCTSTR ctx)
+ Context(const char* ctx)
: _ctx(ctx)
{
_last = s_current;
s_current = this;
}
- Context(LPCTSTR ctx, LPCSTR obj)
+ Context(const char* ctx, LPCSTR obj)
: _ctx(ctx),
_obj(obj)
{
s_current = this;
}
- Context(LPCTSTR ctx, LPCWSTR obj)
+ Context(const char* ctx, LPCWSTR obj)
: _ctx(ctx),
_obj(obj)
{
s_current = this;
}
+ Context(const Context& other)
+ : _ctx(other._ctx),
+ _obj(other._obj)
+ {
+ _last = NULL;
+ }
+
~Context()
{
- s_current = _last;
+ if (_last) {
+ s_current = _last;
+ _last = NULL;
+ }
}
- LPCTSTR _ctx;
+ String toString() const;
+ String getStackTrace() const;
+
+ const char* _ctx;
String _obj;
- static Context current() {return *s_current;}
+ static Context& current() {return *s_current;}
protected:
Context* _last;
- static Context* s_current;
+ static Context* s_current; ///@todo use TLS
static Context s_main;
};
#define CONTEXT_OBJ __ctx__._obj
-#define CONTEXT(c) Context __ctx__(TEXT(c))
-#define OBJ_CONTEXT(c, o) Context __ctx__(TEXT(c), o);
+#define CONTEXT(c) Context __ctx__(c)
+#define CURRENT_CONTEXT Context::current()
+#define OBJ_CONTEXT(c, o) Context __ctx__(c, o)
-#endif // __cplusplus
+extern bool SplitFileSysURL(LPCTSTR url, String& dir_out, String& fname_out);
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef _MSC_VER
-#define LONGLONGARG TEXT("I64")
-#else
-#define LONGLONGARG TEXT("L")
-#endif
-
-
-#ifndef _tcsrchr
-#ifdef UNICODE
-#define _tcsrchr wcsrchr
-#else
-#define _tcsrchr strrchr
-#endif
-#endif
-
-#ifndef _stprintf
-#ifdef UNICODE
-#define _stprintf wcsprintf
-#else
-#define _stprintf sprintf
-#endif
-#endif
-
-
-#ifdef __WINE__
-#ifdef UNICODE
-extern void _wsplitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
-#else
-extern void _splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext);
-#endif
-#endif
-
-#ifndef FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
-#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040
-#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
-#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
-#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
-#endif
-
-
-#define SetDlgCtrlID(hwnd, id) SetWindowLong(hwnd, GWL_ID, id)
-#define SetWindowStyle(hwnd, val) (DWORD)SetWindowLong(hwnd, GWL_STYLE, val)
-#define SetWindowExStyle(h, val) (DWORD)SetWindowLong(hwnd, GWL_EXSTYLE, val)
-#define Window_SetIcon(hwnd, type, hicon) (HICON)SendMessage(hwnd, WM_SETICON, type, (LPARAM)(hicon))
-
-
-
- // center window in respect to its parent window
-extern void CenterWindow(HWND hwnd);
-
- // move window into visibility
-extern void MoveVisible(HWND hwnd);
-
- // display error message
-extern void display_error(HWND hwnd, DWORD error);
-
- // convert time_t to WIN32 FILETIME
-extern BOOL time_to_filetime(const time_t* t, FILETIME* ftime);
-
- // search for windows of a specific classname
-extern int find_window_class(LPCTSTR classname);
-
- // create a bitmap from an icon
-extern HBITMAP create_bitmap_from_icon(HICON hIcon, HBRUSH hbrush_bkgnd, HDC hdc_wnd);
-
- // launch a program or document file
-extern BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow);
-#ifdef UNICODE
-extern BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow);
-#else
-#define launch_fileA launch_file
-#endif
-
- // call an DLL export like rundll32
-BOOL RunDLL(HWND hwnd, LPCTSTR dllname, LPCSTR procname, LPCTSTR cmdline, UINT nCmdShow);
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
+#endif // __cplusplus