2 * Copyright 2003, 2004, 2005 Martin Fuchs
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 // Martin Fuchs, 23.07.2003
31 //#include <shellapi.h>
37 DWORD WINAPI
Thread::ThreadProc(void* para
)
39 Thread
* pThis
= (Thread
*) para
;
41 int ret
= pThis
->Run();
43 pThis
->_alive
= false;
49 void CenterWindow(HWND hwnd
)
52 GetWindowRect(hwnd
, &rt
);
57 for(HWND wh
=hwnd
; (wh
=GetWindow(wh
,GW_OWNER
))!=0; )
58 if (((style
=GetWindowStyle(wh
))&WS_VISIBLE
) && !(style
&WS_MINIMIZE
))
62 GetWindowRect(owner
, &prt
);
64 SystemParametersInfo(SPI_GETWORKAREA
, 0, &prt
, 0); //@@ GetDesktopWindow() wäre auch hilfreich.
66 SetWindowPos(hwnd
, 0, (prt
.left
+prt
.right
+rt
.left
-rt
.right
)/2,
67 (prt
.top
+prt
.bottom
+rt
.top
-rt
.bottom
)/2, 0,0, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOZORDER
);
72 void MoveVisible(HWND hwnd
)
75 GetWindowRect(hwnd
, &rc
);
76 int left
=rc
.left
, top
=rc
.top
;
78 int xmax
= GetSystemMetrics(SM_CXSCREEN
);
79 int ymax
= GetSystemMetrics(SM_CYSCREEN
);
83 else if (rc
.right
> xmax
)
84 if ((rc
.left
-=rc
.right
-xmax
) < 0)
89 else if (rc
.bottom
> ymax
)
90 if ((rc
.top
-=rc
.bottom
-ymax
) < 0)
93 if (rc
.left
!=left
|| rc
.top
!=top
)
94 SetWindowPos(hwnd
, 0, rc
.left
,rc
.top
, 0,0, SWP_NOZORDER
|SWP_NOSIZE
|SWP_NOACTIVATE
);
98 void display_error(HWND hwnd
, DWORD error
) //@@ CONTEXT mit ausgeben -> display_error(HWND hwnd, const Exception& e)
102 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
103 0, error
, MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
), (PTSTR
)&msg
, 0, NULL
)) {
104 LOG(FmtString(TEXT("display_error(%#x): %s"), error
, msg
));
107 MessageBox(hwnd
, msg
, TEXT("ROS Explorer"), MB_OK
);
109 if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE
)
110 MessageBox(0, msg
, TEXT("ROS Explorer"), MB_OK
);
112 LOG(FmtString(TEXT("Unknown Error %#x"), error
));
114 FmtString
msg(TEXT("Unknown Error %#x"), error
);
117 MessageBox(hwnd
, msg
, TEXT("ROS Explorer"), MB_OK
);
119 if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE
)
120 MessageBox(0, msg
, TEXT("ROS Explorer"), MB_OK
);
127 Context
Context::s_main("-NO-CONTEXT-");
128 Context
* Context::s_current
= &Context::s_main
;
130 String
Context::toString() const
135 str
.appendf(TEXT("\nObject: %s"), (LPCTSTR
)_obj
);
140 String
Context::getStackTrace() const
144 str
<< "Context Trace:\n";
146 for(const Context
*p
=this; p
&& p
!=&s_main
; p
=p
->_last
) {
147 str
<< "- " << p
->_ctx
;
149 if (!p
->_obj
.empty())
150 str
<< " obj=" << ANS(p
->_obj
);
159 BOOL
time_to_filetime(const time_t* t
, FILETIME
* ftime
)
161 #ifdef __STDC_WANT_SECURE_LIB__
164 struct tm
* tm
= &tm_
;
166 if (gmtime_s(tm
, t
) != 0)
169 struct tm
* tm
= gmtime(t
);
176 stime
.wYear
= tm
->tm_year
+1900;
177 stime
.wMonth
= tm
->tm_mon
+1;
178 stime
.wDayOfWeek
= (WORD
)-1;
179 stime
.wDay
= tm
->tm_mday
;
180 stime
.wHour
= tm
->tm_hour
;
181 stime
.wMinute
= tm
->tm_min
;
182 stime
.wSecond
= tm
->tm_sec
;
183 stime
.wMilliseconds
= 0;
185 return SystemTimeToFileTime(&stime
, ftime
);
189 BOOL
launch_file(HWND hwnd
, LPCTSTR cmd
, UINT nCmdShow
, LPCTSTR parameters
)
191 CONTEXT("launch_file()");
193 HINSTANCE hinst
= ShellExecute(hwnd
, NULL
/*operation*/, cmd
, parameters
, NULL
/*dir*/, nCmdShow
);
195 if ((int)hinst
<= 32) {
196 display_error(hwnd
, GetLastError());
204 BOOL
launch_fileA(HWND hwnd
, LPSTR cmd
, UINT nCmdShow
, LPCSTR parameters
)
206 HINSTANCE hinst
= ShellExecuteA(hwnd
, NULL
/*operation*/, cmd
, parameters
, NULL
/*dir*/, nCmdShow
);
208 if ((int)hinst
<= 32) {
209 display_error(hwnd
, GetLastError());
218 /* search for already running instance */
220 static int g_foundPrevInstance
= 0;
222 static BOOL CALLBACK
EnumWndProc(HWND hwnd
, LPARAM lparam
)
226 GetClassName(hwnd
, cls
, 128);
228 if (!lstrcmp(cls
, (LPCTSTR
)lparam
)) {
229 g_foundPrevInstance
++;
236 /* search for window of given class name to allow only one running instance */
237 int find_window_class(LPCTSTR classname
)
239 EnumWindows(EnumWndProc
, (LPARAM
)classname
);
241 if (g_foundPrevInstance
)
248 String
get_windows_version_str()
250 OSVERSIONINFOEX osvi
= {sizeof(OSVERSIONINFOEX
)};
254 if (!(osvie_val
= GetVersionEx((OSVERSIONINFO
*)&osvi
))) {
255 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
257 if (!GetVersionEx((OSVERSIONINFO
*)&osvi
))
261 switch(osvi
.dwPlatformId
) {
262 case VER_PLATFORM_WIN32_NT
:
263 #ifdef __REACTOS__ // This work around can be removed if ReactOS gets a unique version number.
264 str
= TEXT("ReactOS");
266 if (osvi
.dwMajorVersion
<= 4)
267 str
= TEXT("Microsoft Windows NT");
268 else if (osvi
.dwMajorVersion
==5 && osvi
.dwMinorVersion
==0)
269 str
= TEXT("Microsoft Windows 2000");
270 else if (osvi
.dwMajorVersion
==5 && osvi
.dwMinorVersion
==1)
271 str
= TEXT("Microsoft Windows XP");
275 if (osvi
.wProductType
== VER_NT_WORKSTATION
) {
276 if (osvi
.wSuiteMask
& VER_SUITE_PERSONAL
)
277 str
+= TEXT(" Personal");
279 str
+= TEXT(" Professional");
280 } else if (osvi
.wProductType
== VER_NT_SERVER
) {
281 if (osvi
.wSuiteMask
& VER_SUITE_DATACENTER
)
282 str
+= TEXT(" DataCenter Server");
283 else if (osvi
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
284 str
+= TEXT(" Advanced Server");
286 str
+= TEXT(" Server");
287 } else if (osvi
.wProductType
== VER_NT_DOMAIN_CONTROLLER
) {
288 str
+= TEXT(" Domain Controller");
295 if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE
, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE
, &hkey
)) {
296 RegQueryValueEx(hkey
, TEXT("ProductType"), NULL
, NULL
, (LPBYTE
)type
, &dwBufLen
);
299 if (!_tcsicmp(TEXT("WINNT"), type
))
300 str
+= TEXT(" Workstation");
301 else if (!_tcsicmp(TEXT("LANMANNT"), type
))
302 str
+= TEXT(" Server");
303 else if (!_tcsicmp(TEXT("SERVERNT"), type
))
304 str
+= TEXT(" Advanced Server");
309 case VER_PLATFORM_WIN32_WINDOWS
:
310 if (osvi
.dwMajorVersion
>4 ||
311 (osvi
.dwMajorVersion
==4 && osvi
.dwMinorVersion
>0)) {
312 if (osvi
.dwMinorVersion
== 90)
313 str
= TEXT("Microsoft Windows ME");
315 str
= TEXT("Microsoft Windows 98");
317 if (osvi
.szCSDVersion
[1] == 'A')
320 str
= TEXT("Microsoft Windows 95");
322 if (osvi
.szCSDVersion
[1]=='B' || osvi
.szCSDVersion
[1]=='C')
323 str
+= TEXT(" OSR2");
327 case VER_PLATFORM_WIN32s
:
328 str
= TEXT("Microsoft Win32s");
336 if (osvi
.dwMajorVersion
<= 4)
337 vstr
.printf(TEXT(" Version %d.%d %s Build %d"),
338 osvi
.dwMajorVersion
, osvi
.dwMinorVersion
,
339 osvi
.szCSDVersion
, osvi
.dwBuildNumber
&0xFFFF);
341 vstr
.printf(TEXT(" %s (Build %d)"), osvi
.szCSDVersion
, osvi
.dwBuildNumber
&0xFFFF);
347 typedef void (WINAPI
*RUNDLLPROC
)(HWND hwnd
, HINSTANCE hinst
, LPCTSTR cmdline
, DWORD nCmdShow
);
349 BOOL
RunDLL(HWND hwnd
, LPCTSTR dllname
, LPCSTR procname
, LPCTSTR cmdline
, UINT nCmdShow
)
351 HMODULE hmod
= LoadLibrary(dllname
);
357 It is possible to create a Unicode version of the function.
358 Rundll32 first tries to find a function named EntryPointW.
359 If it cannot find this function, it tries EntryPointA, then EntryPoint.
360 To create a DLL that supports ANSI on Windows 95/98/Me and Unicode otherwise,
361 export two functions: EntryPointW and EntryPoint.
363 RUNDLLPROC proc
= (RUNDLLPROC
)GetProcAddress(hmod
, procname
);
369 proc(hwnd
, hmod
, cmdline
, nCmdShow
);
378 #define CONTROL_RUNDLL "Control_RunDLLW"
380 #define CONTROL_RUNDLL "Control_RunDLLA"
383 BOOL
launch_cpanel(HWND hwnd
, LPCTSTR applet
)
385 TCHAR parameters
[MAX_PATH
];
387 _tcscpy(parameters
, TEXT("shell32.dll,Control_RunDLL "));
388 _tcscat(parameters
, applet
);
390 return ((int)ShellExecute(hwnd
, TEXT("open"), TEXT("rundll32.exe"), parameters
, NULL
, SW_SHOWDEFAULT
) > 32);
394 BOOL
RecursiveCreateDirectory(LPCTSTR path_in
)
396 TCHAR path
[MAX_PATH
], hole_path
[MAX_PATH
];
398 _tcscpy(hole_path
, path_in
);
403 for(d
=hole_path
; *d
&& *d
!='/' && *d
!='\\'; ++d
) {
410 LPTSTR dir
= hole_path
+ drv_len
;
413 LPTSTR p
= hole_path
+ (l
=_tcslen(hole_path
));
415 while(--p
>=hole_path
&& (*p
=='/' || *p
=='\\'))
418 WIN32_FIND_DATA w32fd
;
420 HANDLE hFind
= FindFirstFile(hole_path
, &w32fd
);
422 if (hFind
== INVALID_HANDLE_VALUE
) {
423 _tcsncpy(path
, hole_path
, drv_len
);
426 for(p
=dir
; *p
=='/'||*p
=='\\'; p
++)
430 memcpy(path
, hole_path
, i
*sizeof(TCHAR
));
432 for(; hole_path
[i
] && hole_path
[i
]!='/' && hole_path
[i
]!='\\'; i
++)
433 path
[i
] = hole_path
[i
];
437 hFind
= FindFirstFile(path
, &w32fd
);
439 if (hFind
!= INVALID_HANDLE_VALUE
)
442 LOG(FmtString(TEXT("CreateDirectory(\"%s\")"), path
));
444 if (!CreateDirectory(path
, 0))
455 DWORD
RegGetDWORDValue(HKEY root
, LPCTSTR path
, LPCTSTR valueName
, DWORD def
)
460 if (!RegOpenKey(root
, path
, &hkey
)) {
461 DWORD len
= sizeof(ret
);
463 if (RegQueryValueEx(hkey
, valueName
, 0, NULL
, (LPBYTE
)&ret
, &len
))
474 BOOL
RegSetDWORDValue(HKEY root
, LPCTSTR path
, LPCTSTR valueName
, DWORD value
)
479 if (!RegOpenKey(root
, path
, &hkey
)) {
480 ret
= RegSetValueEx(hkey
, valueName
, 0, REG_DWORD
, (LPBYTE
)&value
, sizeof(value
));
489 BOOL
exists_path(LPCTSTR path
)
493 HANDLE hfind
= FindFirstFile(path
, &fd
);
495 if (hfind
!= INVALID_HANDLE_VALUE
) {
504 bool SplitFileSysURL(LPCTSTR url
, String
& dir_out
, String
& fname_out
)
506 if (!_tcsnicmp(url
, TEXT("file://"), 7)) {
509 // remove third slash in front of drive characters
514 if (exists_path(url
)) {
515 TCHAR path
[_MAX_PATH
];
517 // convert slashes to back slashes
518 GetFullPathName(url
, COUNTOF(path
), path
, NULL
);
520 if (GetFileAttributes(path
) & FILE_ATTRIBUTE_DIRECTORY
)
523 TCHAR drv
[_MAX_DRIVE
], dir
[_MAX_DIR
], fname
[_MAX_FNAME
], ext
[_MAX_EXT
];
525 _tsplitpath_s(path
, drv
, COUNTOF(drv
), dir
, COUNTOF(dir
), fname
, COUNTOF(fname
), ext
, COUNTOF(ext
));
526 _stprintf(path
, TEXT("%s%s"), drv
, dir
);
528 fname_out
.printf(TEXT("%s%s"), fname
, ext
);