* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef __WINE__
+#include "config.h"
+#include "wine/port.h"
+
+/* for unix filesystem function calls */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#endif
+
+#define COBJMACROS
+
#include "winefile.h"
#include "resource.h"
BOOL header_wdths_ok;
TCHAR path[MAX_PATH];
+ TCHAR filter_pattern[MAX_PATH];
+ int filter_flags;
Root root;
SORT_ORDER sortOrder;
} ChildWnd;
-extern void WineLicense(HWND hwnd);
-extern void WineWarranty(HWND hwnd);
-
-
-#ifdef __WINE__
-
-/* functions in unixcalls.c */
-
-extern void call_getcwd(char* buffer, size_t len);
-extern void* call_opendir(const char* path);
-extern int call_readdir(void* pdir, char* name, unsigned* pinode);
-extern void call_closedir(void* pdir);
-
-extern int call_stat(
- const char* path, int* pis_dir,
- unsigned long* psize_low, unsigned long* psize_high,
- time_t* patime, time_t* pmtime,
- unsigned long* plinks
-);
-
-/* call vswprintf() in msvcrt.dll */
-int swprintf(wchar_t* buffer, const wchar_t* fmt, ...)
-{
- static int (__cdecl *vswprintf)(wchar_t*, const wchar_t*, va_list);
-
- va_list ap;
- int ret;
-
- if (!vswprintf) {
- HMODULE hmod = LoadLibraryA("msvcrt");
- vswprintf = (int(__cdecl*)(wchar_t*,const wchar_t*,va_list)) GetProcAddress(hmod, "vswprintf");
- }
-
- va_start(ap, fmt);
- ret = vswprintf(buffer, fmt, ap);
- va_end(ap);
-
- return 0;
-}
-
-
-#define TMP_ALLOC(s) HeapAlloc(GetProcessHeap(), 0, s)
-#define TMP_FREE(p) HeapFree(GetProcessHeap(), 0, p)
-
-#else
-
-#define TMP_ALLOC(s) alloca(s)
-#define TMP_FREE(p)
-
-#endif
-
static void read_directory(Entry* dir, LPCTSTR path, SORT_ORDER sortOrder, HWND hwnd);
-static void set_curdir(ChildWnd* child, Entry* entry, HWND hwnd);
+static void set_curdir(ChildWnd* child, Entry* entry, int idx, HWND hwnd);
+static void refresh_child(ChildWnd* child);
+static void refresh_drives(void);
static void get_path(Entry* dir, PTSTR path);
+static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols);
-LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
-LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
-LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
+static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
+static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
+static LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
/* globals */
WINEFILE_GLOBALS Globals;
+static int last_split;
+
/* some common string constants */
const static TCHAR sEmpty[] = {'\0'};
}
+/* display network error message using WNetGetLastError() */
+static void display_network_error(HWND hwnd)
+{
+ TCHAR msg[BUFFER_LEN], provider[BUFFER_LEN], b2[BUFFER_LEN];
+ DWORD error;
+
+ if (WNetGetLastError(&error, msg, BUFFER_LEN, provider, BUFFER_LEN) == NO_ERROR)
+ MessageBox(hwnd, msg, RS(b2,IDS_WINEFILE), MB_OK);
+}
+
+
+#ifdef __WINE__
+
+#ifdef UNICODE
+
+/* call vswprintf() in msvcrt.dll */
+/*TODO: fix swprintf() in non-msvcrt mode, so that this dynamic linking function can be removed */
+static int msvcrt_swprintf(WCHAR* buffer, const WCHAR* fmt, ...)
+{
+ static int (__cdecl *pvswprintf)(WCHAR*, const WCHAR*, va_list) = NULL;
+ va_list ap;
+ int ret;
+
+ if (!pvswprintf) {
+ HMODULE hModMsvcrt = LoadLibraryA("msvcrt");
+ pvswprintf = (int(__cdecl*)(WCHAR*,const WCHAR*,va_list)) GetProcAddress(hModMsvcrt, "vswprintf");
+ }
+
+ va_start(ap, fmt);
+ ret = (*pvswprintf)(buffer, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+static LPCWSTR my_wcsrchr(LPCWSTR str, WCHAR c)
+{
+ LPCWSTR p = str;
+
+ while(*p)
+ ++p;
+
+ do {
+ if (--p < str)
+ return NULL;
+ } while(*p != c);
+
+ return p;
+}
+
+#define _tcsrchr my_wcsrchr
+#else /* UNICODE */
+#define _tcsrchr strrchr
+#endif /* UNICODE */
+
+#endif /* __WINE__ */
+
+
/* allocate and initialise a directory entry */
-static Entry* alloc_entry()
+static Entry* alloc_entry(void)
{
Entry* entry = (Entry*) malloc(sizeof(Entry));
DestroyIcon(entry->hicon);
if (entry->folder && entry->folder!=Globals.iDesktop)
- (*entry->folder->lpVtbl->Release)(entry->folder);
+ IShellFolder_Release(entry->folder);
if (entry->pidl)
- (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, entry->pidl);
+ IMalloc_Free(Globals.iMalloc, entry->pidl);
#endif
free(entry);
if (hFind != INVALID_HANDLE_VALUE) {
do {
+#ifdef _NO_EXTENSIONS
+ /* hide directory entry "." */
+ if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ LPCTSTR name = w32fd.cFileName;
+
+ if (name[0]=='.' && name[1]=='\0')
+ continue;
+ }
+#endif
entry = alloc_entry();
if (!first_entry)
entry->scanned = FALSE;
entry->level = level;
-#ifdef _NO_EXTENSIONS
- /* hide directory entry "." */
- if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- LPCTSTR name = entry->data.cFileName;
-
- if (name[0]=='.' && name[1]=='\0')
- continue;
- }
-#else
+#ifndef _NO_EXTENSIONS
entry->etype = ET_WINDOWS;
entry->bhfi_valid = FALSE;
#endif
last = entry;
- } while(FindNextFile(hFind, &entry->data));
+ } while(FindNextFile(hFind, &w32fd));
- last->next = NULL;
+ if (last)
+ last->next = NULL;
FindClose(hFind);
}
Entry* first_entry = NULL;
Entry* last = NULL;
Entry* entry;
- void* pdir;
+ DIR* pdir;
+ int level = dir->level + 1;
#ifdef UNICODE
char cpath[MAX_PATH];
const char* cpath = path;
#endif
- pdir = call_opendir(cpath);
-
- int level = dir->level + 1;
+ pdir = opendir(cpath);
if (pdir) {
- char buffer[MAX_PATH];
- time_t atime, mtime;
- unsigned inode;
- int is_dir;
+ struct stat st;
+ struct dirent* ent;
+ char buffer[MAX_PATH], *p;
const char* s;
- char* p;
for(p=buffer,s=cpath; *s; )
*p++ = *s++;
if (p==buffer || p[-1]!='/')
*p++ = '/';
- while(call_readdir(pdir, p, &inode)) {
+ while((ent=readdir(pdir))) {
entry = alloc_entry();
if (!first_entry)
entry->etype = ET_UNIX;
+ strcpy(p, ent->d_name);
#ifdef UNICODE
MultiByteToWideChar(CP_UNIXCP, 0, p, -1, entry->data.cFileName, MAX_PATH);
#else
lstrcpy(entry->data.cFileName, p);
#endif
- entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
+ if (!stat(buffer, &st)) {
+ entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
- if (!call_stat(buffer, &is_dir,
- &entry->data.nFileSizeLow, &entry->data.nFileSizeHigh,
- &atime, &mtime, &entry->bhfi.nNumberOfLinks))
- {
- if (is_dir)
+ if (S_ISDIR(st.st_mode))
entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+ entry->data.nFileSizeLow = st.st_size & 0xFFFFFFFF;
+ entry->data.nFileSizeHigh = st.st_size >> 32;
+
memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME));
- time_to_filetime(&atime, &entry->data.ftLastAccessTime);
- time_to_filetime(&mtime, &entry->data.ftLastWriteTime);
+ time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime);
+ time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime);
- entry->bhfi.nFileIndexLow = inode;
+ entry->bhfi.nFileIndexLow = ent->d_ino;
entry->bhfi.nFileIndexHigh = 0;
+ entry->bhfi.nNumberOfLinks = st.st_nlink;
+
entry->bhfi_valid = TRUE;
} else {
entry->data.nFileSizeLow = 0;
last = entry;
}
- last->next = NULL;
+ if (last)
+ last->next = NULL;
- call_closedir(pdir);
+ closedir(pdir);
}
dir->down = first_entry;
#ifdef _SHELL_FOLDERS
#ifdef UNICODE
-#define tcscpyn strcpyn
#define get_strret get_strretW
#define path_from_pidl path_from_pidlW
#else
-#define tcscpyn wcscpyn
#define get_strret get_strretA
#define path_from_pidl path_from_pidlA
#endif
-static LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
+static void free_strret(STRRET* str)
{
- LPCSTR s;
- LPSTR d = dest;
+ if (str->uType == STRRET_WSTR)
+ IMalloc_Free(Globals.iMalloc, str->UNION_MEMBER(pOleStr));
+}
- for(s=source; count&&(*d++=*s++); )
- count--;
- return dest;
-}
+#ifndef UNICODE
-static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
+static LPSTR strcpyn(LPSTR dest, LPCSTR source, size_t count)
{
- LPCWSTR s;
- LPWSTR d = dest;
+ LPCSTR s;
+ LPSTR d = dest;
for(s=source; count&&(*d++=*s++); )
count--;
return dest;
}
-
static void get_strretA(STRRET* str, const SHITEMID* shiid, LPSTR buffer, int len)
{
switch(str->uType) {
}
}
+static HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len)
+{
+ STRRET str;
+
+ /* SHGDN_FORPARSING: get full path of id list */
+ HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
+
+ if (SUCCEEDED(hr)) {
+ get_strretA(&str, &pidl->mkid, buffer, len);
+ free_strret(&str);
+ } else
+ buffer[0] = '\0';
+
+ return hr;
+}
+
+#endif
+
+static LPWSTR wcscpyn(LPWSTR dest, LPCWSTR source, size_t count)
+{
+ LPCWSTR s;
+ LPWSTR d = dest;
+
+ for(s=source; count&&(*d++=*s++); )
+ count--;
+
+ return dest;
+}
+
static void get_strretW(STRRET* str, const SHITEMID* shiid, LPWSTR buffer, int len)
{
switch(str->uType) {
}
-static void free_strret(STRRET* str)
-{
- if (str->uType == STRRET_WSTR)
- (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, str->UNION_MEMBER(pOleStr));
-}
-
-
-HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags)
+static HRESULT name_from_pidl(IShellFolder* folder, LPITEMIDLIST pidl, LPTSTR buffer, int len, SHGDNF flags)
{
STRRET str;
- HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, flags, &str);
+ HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, flags, &str);
if (SUCCEEDED(hr)) {
get_strret(&str, &pidl->mkid, buffer, len);
}
-HRESULT path_from_pidlA(IShellFolder* folder, LPITEMIDLIST pidl, LPSTR buffer, int len)
-{
- STRRET str;
-
- /* SHGDN_FORPARSING: get full path of id list */
- HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str);
-
- if (SUCCEEDED(hr)) {
- get_strretA(&str, &pidl->mkid, buffer, len);
- free_strret(&str);
- } else
- buffer[0] = '\0';
-
- return hr;
-}
-
-HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len)
+static HRESULT path_from_pidlW(IShellFolder* folder, LPITEMIDLIST pidl, LPWSTR buffer, int len)
{
STRRET str;
/* SHGDN_FORPARSING: get full path of id list */
- HRESULT hr = (*folder->lpVtbl->GetDisplayNameOf)(folder, pidl, SHGDN_FORPARSING, &str);
+ HRESULT hr = IShellFolder_GetDisplayNameOf(folder, pidl, SHGDN_FORPARSING, &str);
if (SUCCEEDED(hr)) {
get_strretW(&str, &pidl->mkid, buffer, len);
MultiByteToWideChar(CP_ACP, 0, path, -1, buffer, MAX_PATH);
#endif
- hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
+ hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
if (FAILED(hr))
return NULL;
LPITEMIDLIST pidl;
ULONG len;
- hr = (*Globals.iDesktop->lpVtbl->ParseDisplayName)(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
+ hr = IShellFolder_ParseDisplayName(Globals.iDesktop, hwnd, NULL, buffer, &len, &pidl, NULL);
if (SUCCEEDED(hr))
return pidl;
}
-HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl)
+static HICON extract_icon(IShellFolder* folder, LPCITEMIDLIST pidl)
{
IExtractIcon* pExtract;
- if (SUCCEEDED((*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) {
+ if (SUCCEEDED(IShellFolder_GetUIObjectOf(folder, 0, 1, (LPCITEMIDLIST*)&pidl, &IID_IExtractIcon, 0, (LPVOID*)&pExtract))) {
TCHAR path[_MAX_PATH];
unsigned flags;
HICON hicon;
break;
/* copy first element of item idlist */
- next_pidl = (*Globals.iMalloc->lpVtbl->Alloc)(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
+ next_pidl = IMalloc_Alloc(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
memcpy(next_pidl, pidl, pidl->mkid.cb);
((LPITEMIDLIST)((LPBYTE)next_pidl+pidl->mkid.cb))->mkid.cb = 0;
- hr = (*folder->lpVtbl->BindToObject)(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child);
+ hr = IShellFolder_BindToObject(folder, next_pidl, 0, &IID_IShellFolder, (void**)&child);
if (!SUCCEEDED(hr))
break;
STGMEDIUM medium = {0, {0}, 0};
FORMATETC fmt = {Globals.cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- HRESULT hr = (*folder->lpVtbl->GetUIObjectOf)(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
+ HRESULT hr = IShellFolder_GetUIObjectOf(folder, 0, 1, &pidl, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
if (SUCCEEDED(hr)) {
- hr = (*pDataObj->lpVtbl->GetData)(pDataObj, &fmt, &medium);
+ hr = IDataObject_GetData(pDataObj, &fmt, &medium);
- (*pDataObj->lpVtbl->Release)(pDataObj);
+ IDataObject_Release(pDataObj);
if (SUCCEEDED(hr)) {
LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal));
if (!folder)
return;
- hr = (*folder->lpVtbl->EnumObjects)(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist);
+ hr = IShellFolder_EnumObjects(folder, hwnd, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE, &idlist);
if (SUCCEEDED(hr)) {
for(;;) {
memset(pidls, 0, sizeof(pidls));
- hr = (*idlist->lpVtbl->Next)(idlist, FETCH_ITEM_COUNT, pidls, &cnt);
+ hr = IEnumIDList_Next(idlist, FETCH_ITEM_COUNT, pidls, &cnt);
if (!SUCCEEDED(hr))
break;
attribs = ~SFGAO_FILESYSTEM; /*SFGAO_HASSUBFOLDER|SFGAO_FOLDER; SFGAO_FILESYSTEM sorgt dafür, daß "My Documents" anstatt von "Martin's Documents" angezeigt wird */
- hr = (*folder->lpVtbl->GetAttributesOf)(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs);
+ hr = IShellFolder_GetAttributesOf(folder, 1, (LPCITEMIDLIST*)&pidls[n], &attribs);
if (SUCCEEDED(hr)) {
if (attribs != (SFGAOF)~SFGAO_FILESYSTEM) {
entry->pidl = pidls[n];
if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- hr = (*folder->lpVtbl->BindToObject)(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child);
+ hr = IShellFolder_BindToObject(folder, pidls[n], 0, &IID_IShellFolder, (void**)&child);
if (SUCCEEDED(hr))
entry->folder = child;
}
}
- (*idlist->lpVtbl->Release)(idlist);
+ IEnumIDList_Release(idlist);
}
if (last)
}
/* directories first... */
-static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
+static int __cdecl compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
{
int order1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? TO_DIR: TO_FILE;
int order2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY? TO_DIR: TO_FILE;
}
-static int compareName(const void* arg1, const void* arg2)
+static int __cdecl compareName(const void* arg1, const void* arg2)
{
const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
return lstrcmpi(fd1->cFileName, fd2->cFileName);
}
-static int compareExt(const void* arg1, const void* arg2)
+static int __cdecl compareExt(const void* arg1, const void* arg2)
{
const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
return lstrcmpi(name1, name2);
}
-static int compareSize(const void* arg1, const void* arg2)
+static int __cdecl compareSize(const void* arg1, const void* arg2)
{
const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
return cmp<0? -1: cmp>0? 1: 0;
}
-static int compareDate(const void* arg1, const void* arg2)
+static int __cdecl compareDate(const void* arg1, const void* arg2)
{
const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
}
-static int (*sortFunctions[])(const void* arg1, const void* arg2) = {
+static int (__cdecl *sortFunctions[])(const void* arg1, const void* arg2) = {
compareName, /* SORT_NAME */
compareExt, /* SORT_EXT */
compareSize, /* SORT_SIZE */
len++;
if (len) {
- array = (Entry**) TMP_ALLOC(len*sizeof(Entry*));
+ array = HeapAlloc(GetProcessHeap(), 0, len*sizeof(Entry*));
p = array;
for(entry=dir->down; entry; entry=entry->next)
(*p)->next = 0;
- TMP_FREE(array);
+ HeapFree(GetProcessHeap(), 0, array);
}
}
}
-static ChildWnd* alloc_child_window(LPCTSTR path, LPITEMIDLIST pidl, HWND hwnd)
+static Entry* read_tree(Root* root, LPCTSTR path, LPITEMIDLIST pidl, LPTSTR drv, SORT_ORDER sortOrder, HWND hwnd)
{
- const static TCHAR sBackslash[] = {'\\', '\0'};
#if !defined(_NO_EXTENSIONS) && defined(__WINE__)
const static TCHAR sSlash[] = {'/', '\0'};
#endif
+ const static TCHAR sBackslash[] = {'\\', '\0'};
+
+#ifdef _SHELL_FOLDERS
+ if (pidl)
+ {
+ /* read shell namespace tree */
+ root->drive_type = DRIVE_UNKNOWN;
+ drv[0] = '\\';
+ drv[1] = '\0';
+ load_string(root->volname, IDS_DESKTOP);
+ root->fs_flags = 0;
+ load_string(root->fs, IDS_SHELL);
+
+ return read_tree_shell(root, pidl, sortOrder, hwnd);
+ }
+ else
+#endif
+#if !defined(_NO_EXTENSIONS) && defined(__WINE__)
+ if (*path == '/')
+ {
+ /* read unix file system tree */
+ root->drive_type = GetDriveType(path);
+
+ lstrcat(drv, sSlash);
+ load_string(root->volname, IDS_ROOT_FS);
+ root->fs_flags = 0;
+ load_string(root->fs, IDS_UNIXFS);
+
+ lstrcpy(root->path, sSlash);
+
+ return read_tree_unix(root, path, sortOrder, hwnd);
+ }
+#endif
+
+ /* read WIN32 file system tree */
+ root->drive_type = GetDriveType(path);
+
+ lstrcat(drv, sBackslash);
+ GetVolumeInformation(drv, root->volname, _MAX_FNAME, 0, 0, &root->fs_flags, root->fs, _MAX_DIR);
+
+ lstrcpy(root->path, drv);
+ return read_tree_win(root, path, sortOrder, hwnd);
+}
+
+
+/* flags to filter different file types */
+enum TYPE_FILTER {
+ TF_DIRECTORIES = 0x01,
+ TF_PROGRAMS = 0x02,
+ TF_DOCUMENTS = 0x04,
+ TF_OTHERS = 0x08,
+ TF_HIDDEN = 0x10,
+ TF_ALL = 0x1F
+};
+
+
+static ChildWnd* alloc_child_window(LPCTSTR path, LPITEMIDLIST pidl, HWND hwnd)
+{
TCHAR drv[_MAX_DRIVE+1], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT];
TCHAR b1[BUFFER_LEN];
+ const static TCHAR sAsterics[] = {'*', '\0'};
ChildWnd* child = (ChildWnd*) malloc(sizeof(ChildWnd));
Root* root = &child->root;
_tsplitpath(path, drv, dir, name, ext);
}
- root->entry.level = 0;
-
-#ifdef _SHELL_FOLDERS
- if (pidl)
- {
- root->drive_type = DRIVE_UNKNOWN;
- drv[0] = '\\';
- drv[1] = '\0';
- load_string(root->volname, IDS_DESKTOP);
- root->fs_flags = 0;
- load_string(root->fs, IDS_SHELL);
-
- entry = read_tree_shell(root, pidl, child->sortOrder, hwnd);
- }
- else
-#endif
-#if !defined(_NO_EXTENSIONS) && defined(__WINE__)
- if (*path == '/')
- {
- root->drive_type = GetDriveType(path);
-
- lstrcat(drv, sSlash);
- load_string(root->volname, IDS_ROOT_FS);
- root->fs_flags = 0;
- load_string(root->fs, IDS_UNIXFS);
-
- lstrcpy(root->path, sSlash);
- entry = read_tree_unix(root, path, child->sortOrder, hwnd);
- }
- else
-#endif
- {
- root->drive_type = GetDriveType(path);
+ lstrcpy(child->filter_pattern, sAsterics);
+ child->filter_flags = TF_ALL;
- lstrcat(drv, sBackslash);
- GetVolumeInformation(drv, root->volname, _MAX_FNAME, 0, 0, &root->fs_flags, root->fs, _MAX_DIR);
+ root->entry.level = 0;
- lstrcpy(root->path, drv);
- entry = read_tree_win(root, path, child->sortOrder, hwnd);
- }
+ entry = read_tree(root, path, pidl, drv, child->sortOrder, hwnd);
#ifdef _SHELL_FOLDERS
if (root->entry.etype == ET_SHELL)
child->left.root = &root->entry;
child->right.root = NULL;
- set_curdir(child, entry, hwnd);
+ set_curdir(child, entry, 0, hwnd);
return child;
}
attribs = 0;
if (dir->folder)
- hr = (*dir->folder->lpVtbl->GetAttributesOf)(dir->folder, 1, (LPCITEMIDLIST*)&dir->pidl, &attribs);
+ hr = IShellFolder_GetAttributesOf(dir->folder, 1, (LPCITEMIDLIST*)&dir->pidl, &attribs);
if (SUCCEEDED(hr) && (attribs&SFGAO_FILESYSTEM)) {
IShellFolder* parent = dir->up? dir->up->folder: Globals.iDesktop;
static HHOOK hcbthook;
static ChildWnd* newchild = NULL;
-LRESULT CALLBACK CBTProc(int code, WPARAM wparam, LPARAM lparam)
+static LRESULT CALLBACK CBTProc(int code, WPARAM wparam, LPARAM lparam)
{
if (code==HCBT_CREATEWND && newchild) {
ChildWnd* child = newchild;
newchild = NULL;
child->hwnd = (HWND) wparam;
- SetWindowLong(child->hwnd, GWL_USERDATA, (LPARAM)child);
+ SetWindowLongPtr(child->hwnd, GWLP_USERDATA, (LPARAM)child);
}
return CallNextHookEx(hcbthook, code, wparam, lparam);
ListBox_SetItemHeight(child->left.hwnd, 1, max(Globals.spaceSize.cy,IMAGE_HEIGHT+3));
ListBox_SetItemHeight(child->right.hwnd, 1, max(Globals.spaceSize.cy,IMAGE_HEIGHT+3));
- idx = ListBox_FindItemData(child->left.hwnd, ListBox_GetCurSel(child->left.hwnd), child->left.cur);
+
+ idx = ListBox_FindItemData(child->left.hwnd, 0, child->left.cur);
ListBox_SetCurSel(child->left.hwnd, idx);
return child->hwnd;
int cmdshow;
};
-
static INT_PTR CALLBACK ExecuteDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
static struct ExecuteDialog* dlg;
return 0;
}
+
static INT_PTR CALLBACK DestinationDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
switch(nmsg) {
case WM_INITDIALOG:
- SetWindowLong(hwnd, GWL_USERDATA, lparam);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam);
SetWindowText(GetDlgItem(hwnd, 201), (LPCTSTR)lparam);
return 1;
switch(id) {
case IDOK: {
- LPTSTR dest = (LPTSTR) GetWindowLong(hwnd, GWL_USERDATA);
+ LPTSTR dest = (LPTSTR) GetWindowLongPtr(hwnd, GWLP_USERDATA);
GetWindowText(GetDlgItem(hwnd, 201), dest, MAX_PATH);
EndDialog(hwnd, id);
break;}
}
+struct FilterDialog {
+ TCHAR pattern[MAX_PATH];
+ int flags;
+};
+
+static INT_PTR CALLBACK FilterDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ static struct FilterDialog* dlg;
+
+ switch(nmsg) {
+ case WM_INITDIALOG:
+ dlg = (struct FilterDialog*) lparam;
+ SetWindowText(GetDlgItem(hwnd, IDC_VIEW_PATTERN), dlg->pattern);
+ Button_SetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_DIRECTORIES), (dlg->flags&TF_DIRECTORIES? BST_CHECKED: BST_UNCHECKED));
+ Button_SetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_PROGRAMS), dlg->flags&TF_PROGRAMS? BST_CHECKED: BST_UNCHECKED);
+ Button_SetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_DOCUMENTS), dlg->flags&TF_DOCUMENTS? BST_CHECKED: BST_UNCHECKED);
+ Button_SetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_OTHERS), dlg->flags&TF_OTHERS? BST_CHECKED: BST_UNCHECKED);
+ Button_SetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_HIDDEN), dlg->flags&TF_HIDDEN? BST_CHECKED: BST_UNCHECKED);
+ return 1;
+
+ case WM_COMMAND: {
+ int id = (int)wparam;
+
+ if (id == IDOK) {
+ int flags = 0;
+
+ GetWindowText(GetDlgItem(hwnd, IDC_VIEW_PATTERN), dlg->pattern, MAX_PATH);
+
+ flags |= Button_GetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_DIRECTORIES))&BST_CHECKED? TF_DIRECTORIES: 0;
+ flags |= Button_GetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_PROGRAMS))&BST_CHECKED? TF_PROGRAMS: 0;
+ flags |= Button_GetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_DOCUMENTS))&BST_CHECKED? TF_DOCUMENTS: 0;
+ flags |= Button_GetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_OTHERS))&BST_CHECKED? TF_OTHERS: 0;
+ flags |= Button_GetCheck(GetDlgItem(hwnd,IDC_VIEW_TYPE_HIDDEN))&BST_CHECKED? TF_HIDDEN: 0;
+
+ dlg->flags = flags;
+
+ EndDialog(hwnd, id);
+ } else if (id == IDCANCEL)
+ EndDialog(hwnd, id);
+
+ return 1;}
+ }
+
+ return 0;
+}
+
+
+struct PropertiesDialog {
+ TCHAR path[MAX_PATH];
+ Entry entry;
+ void* pVersionData;
+};
+
+/* Structure used to store enumerated languages and code pages. */
+struct LANGANDCODEPAGE {
+ WORD wLanguage;
+ WORD wCodePage;
+} *lpTranslate;
+
+static LPCSTR InfoStrings[] = {
+ "Comments",
+ "CompanyName",
+ "FileDescription",
+ "FileVersion",
+ "InternalName",
+ "LegalCopyright",
+ "LegalTrademarks",
+ "OriginalFilename",
+ "PrivateBuild",
+ "ProductName",
+ "ProductVersion",
+ "SpecialBuild",
+ NULL
+};
+
+static void PropDlg_DisplayValue(HWND hlbox, HWND hedit)
+{
+ int idx = ListBox_GetCurSel(hlbox);
+
+ if (idx != LB_ERR) {
+ LPCTSTR pValue = (LPCTSTR) ListBox_GetItemData(hlbox, idx);
+
+ if (pValue)
+ SetWindowText(hedit, pValue);
+ }
+}
+
+static void CheckForFileInfo(struct PropertiesDialog* dlg, HWND hwnd, LPCTSTR strFilename)
+{
+ static TCHAR sBackSlash[] = {'\\','\0'};
+ static TCHAR sTranslation[] = {'\\','V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n','\0'};
+ static TCHAR sStringFileInfo[] = {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o','\\',
+ '%','0','4','x','%','0','4','x','\\','%','s','\0'};
+ DWORD dwVersionDataLen = GetFileVersionInfoSize((LPTSTR)strFilename, NULL); /* VC6 and MinGW headers use LPTSTR instead of LPCTSTR */
+
+ if (dwVersionDataLen) {
+ dlg->pVersionData = malloc(dwVersionDataLen);
+
+ if (GetFileVersionInfo((LPTSTR)strFilename, 0, dwVersionDataLen, dlg->pVersionData)) { /* VC6 and MinGW headers use LPTSTR instead of LPCTSTR */
+ LPVOID pVal;
+ UINT nValLen;
+
+ if (VerQueryValue(dlg->pVersionData, sBackSlash, &pVal, &nValLen)) {
+ if (nValLen == sizeof(VS_FIXEDFILEINFO)) {
+ VS_FIXEDFILEINFO* pFixedFileInfo = (VS_FIXEDFILEINFO*)pVal;
+ char buffer[BUFFER_LEN];
+
+ sprintf(buffer, "%d.%d.%d.%d",
+ HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
+ HIWORD(pFixedFileInfo->dwFileVersionLS), LOWORD(pFixedFileInfo->dwFileVersionLS));
+
+ SetDlgItemTextA(hwnd, IDC_STATIC_PROP_VERSION, buffer);
+ }
+ }
+
+ /* Read the list of languages and code pages. */
+ if (VerQueryValue(dlg->pVersionData, sTranslation, &pVal, &nValLen)) {
+ struct LANGANDCODEPAGE* pTranslate = (struct LANGANDCODEPAGE*)pVal;
+ struct LANGANDCODEPAGE* pEnd = (struct LANGANDCODEPAGE*)((LPBYTE)pVal+nValLen);
+
+ HWND hlbox = GetDlgItem(hwnd, IDC_LIST_PROP_VERSION_TYPES);
+
+ /* Read the file description for each language and code page. */
+ for(; pTranslate<pEnd; ++pTranslate) {
+ LPCSTR* p;
+
+ for(p=InfoStrings; *p; ++p) {
+ TCHAR subblock[200];
+#ifdef UNICODE
+ TCHAR infoStr[100];
+#endif
+ LPCTSTR pTxt;
+ UINT nValLen;
+
+ LPCSTR pInfoString = *p;
+#ifdef UNICODE
+ MultiByteToWideChar(CP_ACP, 0, pInfoString, -1, infoStr, 100);
+#else
+#define infoStr pInfoString
+#endif
+ wsprintf(subblock, sStringFileInfo, pTranslate->wLanguage, pTranslate->wCodePage, infoStr);
+
+ /* Retrieve file description for language and code page */
+ if (VerQueryValue(dlg->pVersionData, subblock, (PVOID)&pTxt, &nValLen)) {
+ int idx = ListBox_AddString(hlbox, infoStr);
+ ListBox_SetItemData(hlbox, idx, pTxt);
+ }
+ }
+ }
+
+ ListBox_SetCurSel(hlbox, 0);
+
+ PropDlg_DisplayValue(hlbox, GetDlgItem(hwnd,IDC_LIST_PROP_VERSION_VALUES));
+ }
+ }
+ }
+}
+
+static INT_PTR CALLBACK PropertiesDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ static struct PropertiesDialog* dlg;
+
+ switch(nmsg) {
+ case WM_INITDIALOG: {
+ const static TCHAR sByteFmt[] = {'%','s',' ','B','y','t','e','s','\0'};
+ TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
+ LPWIN32_FIND_DATA pWFD;
+ ULONGLONG size;
+
+ dlg = (struct PropertiesDialog*) lparam;
+ pWFD = (LPWIN32_FIND_DATA) &dlg->entry.data;
+
+ GetWindowText(hwnd, b1, MAX_PATH);
+ wsprintf(b2, b1, pWFD->cFileName);
+ SetWindowText(hwnd, b2);
+
+ format_date(&pWFD->ftLastWriteTime, b1, COL_DATE|COL_TIME);
+ SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_LASTCHANGE), b1);
+
+ size = ((ULONGLONG)pWFD->nFileSizeHigh << 32) | pWFD->nFileSizeLow;
+ _stprintf(b1, sLongNumFmt, size);
+ wsprintf(b2, sByteFmt, b1);
+ SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_SIZE), b2);
+
+ SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_FILENAME), pWFD->cFileName);
+ SetWindowText(GetDlgItem(hwnd, IDC_STATIC_PROP_PATH), dlg->path);
+
+ Button_SetCheck(GetDlgItem(hwnd,IDC_CHECK_READONLY), (pWFD->dwFileAttributes&FILE_ATTRIBUTE_READONLY? BST_CHECKED: BST_UNCHECKED));
+ Button_SetCheck(GetDlgItem(hwnd,IDC_CHECK_ARCHIVE), (pWFD->dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE? BST_CHECKED: BST_UNCHECKED));
+ Button_SetCheck(GetDlgItem(hwnd,IDC_CHECK_COMPRESSED), (pWFD->dwFileAttributes&FILE_ATTRIBUTE_COMPRESSED? BST_CHECKED: BST_UNCHECKED));
+ Button_SetCheck(GetDlgItem(hwnd,IDC_CHECK_HIDDEN), (pWFD->dwFileAttributes&FILE_ATTRIBUTE_HIDDEN? BST_CHECKED: BST_UNCHECKED));
+ Button_SetCheck(GetDlgItem(hwnd,IDC_CHECK_SYSTEM), (pWFD->dwFileAttributes&FILE_ATTRIBUTE_SYSTEM? BST_CHECKED: BST_UNCHECKED));
+
+ CheckForFileInfo(dlg, hwnd, dlg->path);
+ return 1;}
+
+ case WM_COMMAND: {
+ int id = (int)wparam;
+
+ switch(HIWORD(wparam)) {
+ case LBN_SELCHANGE: {
+ HWND hlbox = GetDlgItem(hwnd, IDC_LIST_PROP_VERSION_TYPES);
+ PropDlg_DisplayValue(hlbox, GetDlgItem(hwnd,IDC_LIST_PROP_VERSION_VALUES));
+ break;
+ }
+
+ case BN_CLICKED:
+ if (id==IDOK || id==IDCANCEL)
+ EndDialog(hwnd, id);
+ }
+
+ return 1;}
+
+ case WM_NCDESTROY:
+ free(dlg->pVersionData);
+ dlg->pVersionData = NULL;
+ break;
+ }
+
+ return 0;
+}
+
+static void show_properties_dlg(Entry* entry, HWND hwnd)
+{
+ struct PropertiesDialog dlg;
+
+ memset(&dlg, 0, sizeof(struct PropertiesDialog));
+ get_path(entry, dlg.path);
+ memcpy(&dlg.entry, entry, sizeof(Entry));
+
+ DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_PROPERTIES), hwnd, PropertiesDialogDlgProc, (LPARAM)&dlg);
+}
+
+
#ifndef _NO_EXTENSIONS
static struct FullScreenParameters {
FALSE
};
-void frame_get_clientspace(HWND hwnd, PRECT prect)
+static void frame_get_clientspace(HWND hwnd, PRECT prect)
{
RECT rt;
resize_frame_client(hwnd);
}
-BOOL activate_drive_window(LPCTSTR path)
+static BOOL activate_drive_window(LPCTSTR path)
{
TCHAR drv1[_MAX_DRIVE], drv2[_MAX_DRIVE];
HWND child_wnd;
/* search for a already open window for the same drive */
for(child_wnd=GetNextWindow(Globals.hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
- ChildWnd* child = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
+ ChildWnd* child = (ChildWnd*) GetWindowLongPtr(child_wnd, GWLP_USERDATA);
if (child) {
_tsplitpath(child->root.path, drv2, 0, 0, 0);
return FALSE;
}
-BOOL activate_fs_window(LPCTSTR filesys)
+static BOOL activate_fs_window(LPCTSTR filesys)
{
HWND child_wnd;
/* search for a already open window of the given file system name */
for(child_wnd=GetNextWindow(Globals.hmdiclient,GW_CHILD); child_wnd; child_wnd=GetNextWindow(child_wnd, GW_HWNDNEXT)) {
- ChildWnd* child = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
+ ChildWnd* child = (ChildWnd*) GetWindowLongPtr(child_wnd, GWLP_USERDATA);
if (child) {
if (!lstrcmpi(child->root.fs, filesys)) {
return FALSE;
}
-LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+static LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
break;
case WM_DESTROY:
- /* don't exit desktop when closing file manager window */
- if (!Globals.hwndParent)
- PostQuitMessage(0);
+ PostQuitMessage(0);
break;
+ case WM_INITMENUPOPUP: {
+ HWND hwndClient = (HWND) SendMessage(Globals.hmdiclient, WM_MDIGETACTIVE, 0, 0);
+
+ if (!SendMessage(hwndClient, WM_INITMENUPOPUP, wparam, lparam))
+ return 0;
+ break;}
+
case WM_COMMAND: {
UINT cmd = LOWORD(wparam);
HWND hwndClient = (HWND) SendMessage(Globals.hmdiclient, WM_MDIGETACTIVE, 0, 0);
free(child);
break;}
+ case ID_REFRESH:
+ refresh_drives();
+ break;
+
case ID_WINDOW_CASCADE:
SendMessage(Globals.hmdiclient, WM_MDICASCADE, 0, 0);
break;
if (ChooseFont(&chFont)) {
HWND childWnd;
+ HFONT hFontOld;
+ DeleteObject(Globals.hfont);
Globals.hfont = CreateFontIndirect(&lFont);
- SelectFont(hdc, Globals.hfont);
+ hFontOld = SelectFont(hdc, Globals.hfont);
GetTextExtentPoint32(hdc, sSpace, 1, &Globals.spaceSize);
/* change font in all open child windows */
for(childWnd=GetWindow(Globals.hmdiclient,GW_CHILD); childWnd; childWnd=GetNextWindow(childWnd,GW_HWNDNEXT)) {
- ChildWnd* child = (ChildWnd*) GetWindowLong(childWnd, GWL_USERDATA);
+ ChildWnd* child = (ChildWnd*) GetWindowLongPtr(childWnd, GWLP_USERDATA);
SetWindowFont(child->left.hwnd, Globals.hfont, TRUE);
SetWindowFont(child->right.hwnd, Globals.hfont, TRUE);
ListBox_SetItemHeight(child->left.hwnd, 1, max(Globals.spaceSize.cy,IMAGE_HEIGHT+3));
InvalidateRect(child->left.hwnd, NULL, TRUE);
InvalidateRect(child->right.hwnd, NULL, TRUE);
}
+
+ SelectFont(hdc, hFontOld);
}
else if (CommDlgExtendedError()) {
LoadString(Globals.hInstance, IDS_FONT_SEL_DLG_NAME, dlg_name, BUFFER_LEN);
}
break;}
- case ID_CONNECT_NETWORK_DRIVE:
- WNetConnectionDialog(hwnd, RESOURCETYPE_DISK);
- break;
+ case ID_CONNECT_NETWORK_DRIVE: {
+ DWORD ret = WNetConnectionDialog(hwnd, RESOURCETYPE_DISK);
+ if (ret == NO_ERROR)
+ refresh_drives();
+ else if (ret != (DWORD)-1) {
+ if (ret == ERROR_EXTENDED_ERROR)
+ display_network_error(hwnd);
+ else
+ display_error(hwnd, ret);
+ }
+ break;}
+
+ case ID_DISCONNECT_NETWORK_DRIVE: {
+ DWORD ret = WNetDisconnectDialog(hwnd, RESOURCETYPE_DISK);
+ if (ret == NO_ERROR)
+ refresh_drives();
+ else if (ret != (DWORD)-1) {
+ if (ret == ERROR_EXTENDED_ERROR)
+ display_network_error(hwnd);
+ else
+ display_error(hwnd, ret);
+ }
+ break;}
- case ID_DISCONNECT_NETWORK_DRIVE:
- WNetDisconnectDialog(hwnd, RESOURCETYPE_DISK);
- break;
+#ifndef __MINGW32__ /* SHFormatDrive missing in MinGW (as of 13.5.2005) */
+ case ID_FORMAT_DISK: {
+ UINT sem_org = SetErrorMode(0); /* Get the current Error Mode settings. */
+ SetErrorMode(sem_org & ~SEM_FAILCRITICALERRORS); /* Force O/S to handle */
+ SHFormatDrive(hwnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
+ SetErrorMode(sem_org); /* Put it back the way it was. */
+ break;}
+#endif
case ID_HELP:
WinHelp(hwnd, RS(b1,IDS_WINEFILE), HELP_INDEX, 0);
#ifdef UNICODE
- call_getcwd(cpath, MAX_PATH);
+ getcwd(cpath, MAX_PATH);
MultiByteToWideChar(CP_UNIXCP, 0, cpath, -1, path, MAX_PATH);
#else
- call_getcwd(path, MAX_PATH);
+ getcwd(path, MAX_PATH);
#endif
child = alloc_child_window(path, NULL, hwnd);
case ID_NO_WARRANTY:
WineWarranty(Globals.hMainWnd);
break;
-#endif
case ID_ABOUT_WINE:
ShellAbout(hwnd, RS(b2,IDS_WINE), RS(b1,IDS_WINEFILE), 0);
break;
+#endif
case ID_ABOUT:
ShellAbout(hwnd, RS(b1,IDS_WINEFILE), NULL, 0);
}
+static BOOL pattern_match(LPCTSTR str, LPCTSTR pattern)
+{
+ for( ; *str&&*pattern; str++,pattern++) {
+ if (*pattern == '*') {
+ do pattern++;
+ while(*pattern == '*');
+
+ if (!*pattern)
+ return TRUE;
+
+ for(; *str; str++)
+ if (*str==*pattern && pattern_match(str, pattern))
+ return TRUE;
+
+ return FALSE;
+ }
+ else if (*str!=*pattern && *pattern!='?')
+ return FALSE;
+ }
+
+ if (*str || *pattern)
+ if (*pattern!='*' || pattern[1]!='\0')
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL pattern_imatch(LPCTSTR str, LPCTSTR pattern)
+{
+ TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
+
+ lstrcpy(b1, str);
+ lstrcpy(b2, pattern);
+ CharUpper(b1);
+ CharUpper(b2);
+
+ return pattern_match(b1, b2);
+}
+
+
+enum FILE_TYPE {
+ FT_OTHER = 0,
+ FT_EXECUTABLE = 1,
+ FT_DOCUMENT = 2
+};
+
+static enum FILE_TYPE get_file_type(LPCTSTR filename);
+
+
/* insert listbox entries after index idx */
-static int insert_entries(Pane* pane, Entry* dir, int idx)
+static int insert_entries(Pane* pane, Entry* dir, LPCTSTR pattern, int filter_flags, int idx)
{
Entry* entry = dir;
continue;
#endif
- /* don't display entries "." and ".." in the left pane */
- if (pane->treePane && (entry->data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
- && entry->data.cFileName[0]==TEXT('.'))
- if (
-#ifndef _NO_EXTENSIONS
- entry->data.cFileName[1]==TEXT('\0') ||
-#endif
- (entry->data.cFileName[1]==TEXT('.') && entry->data.cFileName[2]==TEXT('\0')))
+ if (entry->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ /* don't display entries "." and ".." in the left pane */
+ if (pane->treePane && entry->data.cFileName[0]==TEXT('.'))
+ if (
+ #ifndef _NO_EXTENSIONS
+ entry->data.cFileName[1]==TEXT('\0') ||
+ #endif
+ (entry->data.cFileName[1]==TEXT('.') && entry->data.cFileName[2]==TEXT('\0')))
+ continue;
+
+ /* filter directories in right pane */
+ if (!pane->treePane && !(filter_flags&TF_DIRECTORIES))
+ continue;
+ }
+
+ /* filter using the file name pattern */
+ if (pattern)
+ if (!pattern_imatch(entry->data.cFileName, pattern))
continue;
+ /* filter system and hidden files */
+ if (!(filter_flags&TF_HIDDEN) && (entry->data.dwFileAttributes&(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
+ continue;
+
+ /* filter looking at the file type */
+ if ((filter_flags&(TF_PROGRAMS|TF_DOCUMENTS|TF_OTHERS)) != (TF_PROGRAMS|TF_DOCUMENTS|TF_OTHERS))
+ switch(get_file_type(entry->data.cFileName)) {
+ case FT_EXECUTABLE:
+ if (!(filter_flags & TF_PROGRAMS))
+ continue;
+ break;
+
+ case FT_DOCUMENT:
+ if (!(filter_flags & TF_DOCUMENTS))
+ continue;
+ break;
+
+ default: /* TF_OTHERS */
+ if (!(filter_flags & TF_OTHERS))
+ continue;
+ }
+
if (idx != -1)
idx++;
ListBox_InsertItemData(pane->hwnd, idx, entry);
if (pane->treePane && entry->expanded)
- idx = insert_entries(pane, entry->down, idx);
+ idx = insert_entries(pane, entry->down, pattern, filter_flags, idx);
}
ShowWindow(pane->hwnd, SW_SHOW);
}
+static void format_bytes(LPTSTR buffer, LONGLONG bytes)
+{
+ const static TCHAR sFmtGB[] = {'%', '.', '1', 'f', ' ', 'G', 'B', '\0'};
+ const static TCHAR sFmtMB[] = {'%', '.', '1', 'f', ' ', 'M', 'B', '\0'};
+ const static TCHAR sFmtkB[] = {'%', '.', '1', 'f', ' ', 'k', 'B', '\0'};
+
+ float fBytes = (float)bytes;
+
+#ifdef __WINE__ /* work around for incorrect implementation of wsprintf()/_stprintf() in WINE */
+ if (bytes >= 1073741824) /* 1 GB */
+ wsprintf(buffer, sFmtGB, fBytes/1073741824.f+.5f);
+ else if (bytes >= 1048576) /* 1 MB */
+ wsprintf(buffer, sFmtMB, fBytes/1048576.f+.5f);
+ else if (bytes >= 1024) /* 1 kB */
+ wsprintf(buffer, sFmtkB, fBytes/1024.f+.5f);
+#else
+ if (bytes >= 1073741824) /* 1 GB */
+ _stprintf(buffer, sFmtGB, fBytes/1073741824.f+.5f);
+ else if (bytes >= 1048576) /* 1 MB */
+ _stprintf(buffer, sFmtMB, fBytes/1048576.f+.5f);
+ else if (bytes >= 1024) /* 1 kB */
+ _stprintf(buffer, sFmtkB, fBytes/1024.f+.5f);
+#endif
+ else
+ _stprintf(buffer, sLongNumFmt, bytes);
+}
+
+static void set_space_status(void)
+{
+ ULARGE_INTEGER ulFreeBytesToCaller, ulTotalBytes, ulFreeBytes;
+ TCHAR fmt[64], b1[64], b2[64], buffer[BUFFER_LEN];
+
+ if (GetDiskFreeSpaceEx(NULL, &ulFreeBytesToCaller, &ulTotalBytes, &ulFreeBytes)) {
+ format_bytes(b1, ulFreeBytesToCaller.QuadPart);
+ format_bytes(b2, ulTotalBytes.QuadPart);
+ wsprintf(buffer, RS(fmt,IDS_FREE_SPACE_FMT), b1, b2);
+ } else
+ lstrcpy(buffer, sQMarks);
+
+ SendMessage(Globals.hstatusbar, SB_SETTEXT, 0, (LPARAM)buffer);
+}
+
+
static WNDPROC g_orgTreeWndProc;
-static void create_tree_window(HWND parent, Pane* pane, int id, int id_header)
+static void create_tree_window(HWND parent, Pane* pane, int id, int id_header, LPCTSTR pattern, int filter_flags)
{
const static TCHAR sListBox[] = {'L','i','s','t','B','o','x','\0'};
LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
0, 0, 0, 0, parent, (HMENU)id, Globals.hInstance, 0);
- SetWindowLong(pane->hwnd, GWL_USERDATA, (LPARAM)pane);
+ SetWindowLongPtr(pane->hwnd, GWLP_USERDATA, (LPARAM)pane);
g_orgTreeWndProc = SubclassWindow(pane->hwnd, TreeWndProc);
SetWindowFont(pane->hwnd, Globals.hfont, FALSE);
/* insert entries into listbox */
if (entry)
- insert_entries(pane, entry, -1);
+ insert_entries(pane, entry, pattern, filter_flags, -1);
/* calculate column widths */
if (!s_init) {
static void InitChildWindow(ChildWnd* child)
{
- create_tree_window(child->hwnd, &child->left, IDW_TREE_LEFT, IDW_HEADER_LEFT);
- create_tree_window(child->hwnd, &child->right, IDW_TREE_RIGHT, IDW_HEADER_RIGHT);
+ create_tree_window(child->hwnd, &child->left, IDW_TREE_LEFT, IDW_HEADER_LEFT, NULL, TF_ALL);
+ create_tree_window(child->hwnd, &child->right, IDW_TREE_RIGHT, IDW_HEADER_RIGHT, child->filter_pattern, child->filter_flags);
}
return;
if (!FileTimeToLocalFileTime(ft, &lft))
- {err: _tcscpy(buffer,sQMarks); return;}
+ {err: lstrcpy(buffer,sQMarks); return;}
if (!FileTimeToSystemTime(&lft, &systime))
goto err;
}
-static int is_exe_file(LPCTSTR ext)
+static BOOL is_exe_file(LPCTSTR ext)
{
static const TCHAR executable_extensions[][4] = {
{'C','O','M','\0'},
d++;
for(p=executable_extensions; (*p)[0]; p++)
- if (!_tcscmp(ext_buffer, *p))
- return 1;
+ if (!lstrcmpi(ext_buffer, *p))
+ return TRUE;
- return 0;
+ return FALSE;
}
-static int is_registered_type(LPCTSTR ext)
+static BOOL is_registered_type(LPCTSTR ext)
{
- /* TODO */
+ /* check if there exists a classname for this file extension in the registry */
+ if (!RegQueryValue(HKEY_CLASSES_ROOT, ext, NULL, NULL))
+ return TRUE;
- return 1;
+ return FALSE;
+}
+
+static enum FILE_TYPE get_file_type(LPCTSTR filename)
+{
+ LPCTSTR ext = _tcsrchr(filename, '.');
+ if (!ext)
+ ext = sEmpty;
+
+ if (is_exe_file(ext))
+ return FT_EXECUTABLE;
+ else if (is_registered_type(ext))
+ return FT_DOCUMENT;
+ else
+ return FT_OTHER;
}
else
img = IMG_FOLDER;
} else {
- LPCTSTR ext = _tcsrchr(entry->data.cFileName, '.');
- if (!ext)
- ext = sEmpty;
-
- if (is_exe_file(ext))
- img = IMG_EXECUTABLE;
- else if (is_registered_type(ext))
- img = IMG_DOCUMENT;
- else
- img = IMG_FILE;
+ switch(get_file_type(entry->data.cFileName)) {
+ case FT_EXECUTABLE: img = IMG_EXECUTABLE; break;
+ case FT_DOCUMENT: img = IMG_DOCUMENT; break;
+ default: img = IMG_FILE;
+ }
}
} else {
attrs = 0;
)
LineTo(dis->hDC, x, dis->rcItem.bottom);
- if (entry->down && entry->expanded) {
- x += IMAGE_WIDTH+TREE_LINE_DX;
- MoveToEx(dis->hDC, x, dis->rcItem.top+IMAGE_HEIGHT, 0);
- LineTo(dis->hDC, x, dis->rcItem.bottom);
- }
-
SelectClipRgn(dis->hDC, hrgn_org);
if (hrgn_org) DeleteObject(hrgn_org);
/* SelectObject(dis->hDC, holdPen); */
textcolor = RGB(0,0,0);
if (dis->itemState & ODS_FOCUS) {
- textcolor = RGB(255,255,255);
+ textcolor = COLOR_SELECTION_TXT;
bkcolor = COLOR_SELECTION;
} else {
- bkcolor = RGB(255,255,255);
+ bkcolor = GetSysColor(COLOR_WINDOW);
}
hbrush = CreateSolidBrush(bkcolor);
if (visible_cols & COL_ATTRIBUTES) {
#ifdef _NO_EXTENSIONS
const static TCHAR s4Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
- _tcscpy(buffer, s4Tabs);
+ lstrcpy(buffer, s4Tabs);
#else
const static TCHAR s11Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
- _tcscpy(buffer, s11Tabs);
+ lstrcpy(buffer, s11Tabs);
#endif
if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N';
DWORD rights = get_access_mask();
- tcscpy(buffer, sSecTabs);
+ lstrcpy(buffer, sSecTabs);
if (rights & FILE_READ_DATA) buffer[ 0] = 'R';
if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W';
HPEN lastPen;
HPEN hpen;
- if (!(GetVersion() & 0x80000000)) { /* Windows NT? */
+ if (!(GetVersion() & 0x80000000)) { /* Windows NT or higher? */
LOGBRUSH lb = {PS_SOLID, RGB(255,255,255)};
hpen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, 0);
} else
#endif /* _NO_EXTENSIONS */
-static void scan_entry(ChildWnd* child, Entry* entry, HWND hwnd)
+static void scan_entry(ChildWnd* child, Entry* entry, int idx, HWND hwnd)
{
TCHAR path[MAX_PATH];
- int idx = ListBox_GetCurSel(child->left.hwnd);
HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT));
/* delete sub entries in left pane */
}
/* insert found entries in right pane */
- insert_entries(&child->right, entry->down, -1);
+ insert_entries(&child->right, entry->down, child->filter_pattern, child->filter_flags, -1);
calc_widths(&child->right, FALSE);
#ifndef _NO_EXTENSIONS
set_header(&child->right);
dir->expanded = TRUE;
/* insert entries in left pane */
- insert_entries(&child->left, p, idx);
+ insert_entries(&child->left, p, NULL, TF_ALL, idx);
if (!child->header_wdths_ok) {
if (calc_widths(&child->left, FALSE)) {
}
-static void set_curdir(ChildWnd* child, Entry* entry, HWND hwnd)
+static void refresh_right_pane(ChildWnd* child)
+{
+ ListBox_ResetContent(child->right.hwnd);
+ insert_entries(&child->right, child->right.root, child->filter_pattern, child->filter_flags, -1);
+ calc_widths(&child->right, FALSE);
+
+#ifndef _NO_EXTENSIONS
+ set_header(&child->right);
+#endif
+}
+
+static void set_curdir(ChildWnd* child, Entry* entry, int idx, HWND hwnd)
{
TCHAR path[MAX_PATH];
+ if (!entry)
+ return;
+
path[0] = '\0';
child->left.cur = entry;
+
child->right.root = entry->down? entry->down: entry;
child->right.cur = entry;
if (!entry->scanned)
- scan_entry(child, entry, hwnd);
- else {
- ListBox_ResetContent(child->right.hwnd);
- insert_entries(&child->right, entry->down, -1);
- calc_widths(&child->right, FALSE);
-#ifndef _NO_EXTENSIONS
- set_header(&child->right);
-#endif
- }
+ scan_entry(child, entry, idx, hwnd);
+ else
+ refresh_right_pane(child);
get_path(entry, path);
lstrcpy(child->path, path);
SetWindowText(child->hwnd, path);
if (path[0])
- SetCurrentDirectory(path);
+ if (SetCurrentDirectory(path))
+ set_space_status();
}
-BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow)
+static void refresh_child(ChildWnd* child)
{
- HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow);
+ TCHAR path[MAX_PATH], drv[_MAX_DRIVE+1];
+ Entry* entry;
+ int idx;
- if ((int)hinst <= 32) {
- display_error(hwnd, GetLastError());
- return FALSE;
+ get_path(child->left.cur, path);
+ _tsplitpath(path, drv, NULL, NULL, NULL);
+
+ child->right.root = NULL;
+
+ scan_entry(child, &child->root.entry, 0, child->hwnd);
+
+#ifdef _SHELL_FOLDERS
+ if (child->root.entry.etype == ET_SHELL)
+ entry = read_tree(&child->root, NULL, get_path_pidl(path,child->hwnd), drv, child->sortOrder, child->hwnd);
+ else
+#endif
+ entry = read_tree(&child->root, path, NULL, drv, child->sortOrder, child->hwnd);
+
+ if (!entry)
+ entry = &child->root.entry;
+
+ insert_entries(&child->left, child->root.entry.down, NULL, TF_ALL, 0);
+
+ set_curdir(child, entry, 0, child->hwnd);
+
+ idx = ListBox_FindItemData(child->left.hwnd, 0, child->left.cur);
+ ListBox_SetCurSel(child->left.hwnd, idx);
+}
+
+
+static void create_drive_bar(void)
+{
+ TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0};
+#ifndef _NO_EXTENSIONS
+ TCHAR b1[BUFFER_LEN];
+#endif
+ int btn = 1;
+ PTSTR p;
+
+ GetLogicalDriveStrings(BUFFER_LEN, Globals.drives);
+
+ Globals.hdrivebar = CreateToolbarEx(Globals.hMainWnd, WS_CHILD|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST,
+ IDW_DRIVEBAR, 2, Globals.hInstance, IDB_DRIVEBAR, &drivebarBtn,
+ 0, 16, 13, 16, 13, sizeof(TBBUTTON));
+
+#ifndef _NO_EXTENSIONS
+#ifdef __WINE__
+ /* insert unix file system button */
+ b1[0] = '/';
+ b1[1] = '\0';
+ b1[2] = '\0';
+ SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b1);
+
+ drivebarBtn.idCommand = ID_DRIVE_UNIX_FS;
+ SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
+ drivebarBtn.iString++;
+#endif
+#ifdef _SHELL_FOLDERS
+ /* insert shell namespace button */
+ load_string(b1, IDS_SHELL);
+ b1[lstrlen(b1)+1] = '\0';
+ SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b1);
+
+ drivebarBtn.idCommand = ID_DRIVE_SHELL_NS;
+ SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
+ drivebarBtn.iString++;
+#endif
+
+ /* register windows drive root strings */
+ SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)Globals.drives);
+#endif
+
+ drivebarBtn.idCommand = ID_DRIVE_FIRST;
+
+ for(p=Globals.drives; *p; ) {
+#ifdef _NO_EXTENSIONS
+ /* insert drive letter */
+ TCHAR b[3] = {tolower(*p)};
+ SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b);
+#endif
+ switch(GetDriveType(p)) {
+ case DRIVE_REMOVABLE: drivebarBtn.iBitmap = 1; break;
+ case DRIVE_CDROM: drivebarBtn.iBitmap = 3; break;
+ case DRIVE_REMOTE: drivebarBtn.iBitmap = 4; break;
+ case DRIVE_RAMDISK: drivebarBtn.iBitmap = 5; break;
+ default:/*DRIVE_FIXED*/ drivebarBtn.iBitmap = 2;
+ }
+
+ SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
+ drivebarBtn.idCommand++;
+ drivebarBtn.iString++;
+
+ while(*p++);
}
+}
- return TRUE;
+static void refresh_drives(void)
+{
+ RECT rect;
+
+ /* destroy drive bar */
+ DestroyWindow(Globals.hdrivebar);
+ Globals.hdrivebar = 0;
+
+ /* re-create drive bar */
+ create_drive_bar();
+
+ /* update window layout */
+ GetClientRect(Globals.hMainWnd, &rect);
+ SendMessage(Globals.hMainWnd, WM_SIZE, 0, MAKELONG(rect.right, rect.bottom));
}
-#ifdef UNICODE
-BOOL launch_fileA(HWND hwnd, LPSTR cmd, UINT nCmdShow)
+
+static BOOL launch_file(HWND hwnd, LPCTSTR cmd, UINT nCmdShow)
{
- HINSTANCE hinst = ShellExecuteA(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow);
+ HINSTANCE hinst = ShellExecute(hwnd, NULL/*operation*/, cmd, NULL/*parameters*/, NULL/*dir*/, nCmdShow);
if ((int)hinst <= 32) {
display_error(hwnd, GetLastError());
return TRUE;
}
-#endif
-BOOL launch_entry(Entry* entry, HWND hwnd, UINT nCmdShow)
+static BOOL launch_entry(Entry* entry, HWND hwnd, UINT nCmdShow)
{
TCHAR cmd[MAX_PATH];
}
if (shexinfo.lpIDList != entry->pidl)
- (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, shexinfo.lpIDList);
+ IMalloc_Free(Globals.iMalloc, shexinfo.lpIDList);
return ret;
}
int scanned_old = entry->scanned;
if (!scanned_old)
- scan_entry(child, entry, hwnd);
+ scan_entry(child, entry, ListBox_GetCurSel(child->left.hwnd), hwnd);
#ifndef _NO_EXTENSIONS
if (entry->data.cFileName[0]=='.' && entry->data.cFileName[1]=='\0')
if (!pane->treePane) focus_entry: {
int idx = ListBox_FindItemData(child->left.hwnd, ListBox_GetCurSel(child->left.hwnd), entry);
ListBox_SetCurSel(child->left.hwnd, idx);
- set_curdir(child, entry, hwnd);
+ set_curdir(child, entry, idx, hwnd);
}
}
#endif
}
} else {
- launch_entry(entry, child->hwnd, SW_SHOWNORMAL);
+ if (GetKeyState(VK_MENU) < 0)
+ show_properties_dlg(entry, child->hwnd);
+ else
+ launch_entry(entry, child->hwnd, SW_SHOWNORMAL);
}
}
}
+static void set_sort_order(ChildWnd* child, SORT_ORDER sortOrder)
+{
+ if (child->sortOrder != sortOrder) {
+ child->sortOrder = sortOrder;
+ refresh_child(child);
+ }
+}
+
+static void update_view_menu(ChildWnd* child)
+{
+ CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_NAME, child->sortOrder==SORT_NAME? MF_CHECKED: MF_UNCHECKED);
+ CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_TYPE, child->sortOrder==SORT_EXT? MF_CHECKED: MF_UNCHECKED);
+ CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_SIZE, child->sortOrder==SORT_SIZE? MF_CHECKED: MF_UNCHECKED);
+ CheckMenuItem(Globals.hMenuView, ID_VIEW_SORT_DATE, child->sortOrder==SORT_DATE? MF_CHECKED: MF_UNCHECKED);
+}
+
+
+static BOOL is_directory(LPCTSTR target)
+{
+ /*TODO correctly handle UNIX paths */
+ DWORD target_attr = GetFileAttributes(target);
+
+ if (target_attr == INVALID_FILE_ATTRIBUTES)
+ return FALSE;
+
+ return target_attr&FILE_ATTRIBUTE_DIRECTORY? TRUE: FALSE;
+}
+
+static BOOL prompt_target(Pane* pane, LPTSTR source, LPTSTR target)
+{
+ TCHAR path[MAX_PATH];
+ int len;
+
+ get_path(pane->cur, path);
+
+ if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_SELECT_DESTINATION), pane->hwnd, DestinationDlgProc, (LPARAM)path) != IDOK)
+ return FALSE;
+
+ get_path(pane->cur, source);
+
+ /* convert relative targets to absolute paths */
+ if (path[0]!='/' && path[1]!=':') {
+ get_path(pane->cur->up, target);
+ len = lstrlen(target);
+
+ if (target[len-1]!='\\' && target[len-1]!='/')
+ target[len++] = '/';
+
+ lstrcpy(target+len, path);
+ } else
+ lstrcpy(target, path);
+
+ /* If the target already exists as directory, create a new target below this. */
+ if (is_directory(path)) {
+ TCHAR fname[_MAX_FNAME], ext[_MAX_EXT];
+ const static TCHAR sAppend[] = {'%','s','/','%','s','%','s','\0'};
+
+ _tsplitpath(source, NULL, NULL, fname, ext);
+
+ wsprintf(target, sAppend, path, fname, ext);
+ }
+
+ return TRUE;
+}
+
+
static IContextMenu2* s_pctxmenu2 = NULL;
#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
static IContextMenu3* s_pctxmenu3 = NULL;
#endif
-static void CtxMenu_reset()
+static void CtxMenu_reset(void)
{
s_pctxmenu2 = NULL;
#endif
}
-IContextMenu* CtxMenu_query_interfaces(IContextMenu* pcm1)
+static IContextMenu* CtxMenu_query_interfaces(IContextMenu* pcm1)
{
IContextMenu* pcm = NULL;
CtxMenu_reset();
#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
- if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
+ if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
s_pctxmenu3 = (LPCONTEXTMENU3)pcm;
else
#endif
- if ((*pcm1->lpVtbl->QueryInterface)(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
+ if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
s_pctxmenu2 = (LPCONTEXTMENU2)pcm;
if (pcm) {
- (*pcm1->lpVtbl->Release)(pcm1);
+ IUnknown_Release(pcm1);
return pcm;
} else
return pcm1;
static HRESULT ShellFolderContextMenu(IShellFolder* shell_folder, HWND hwndParent, int cidl, LPCITEMIDLIST* apidl, int x, int y)
{
IContextMenu* pcm;
+ BOOL executed = FALSE;
- HRESULT hr = (*shell_folder->lpVtbl->GetUIObjectOf)(shell_folder, hwndParent, cidl, apidl, &IID_IContextMenu, NULL, (LPVOID*)&pcm);
+ HRESULT hr = IShellFolder_GetUIObjectOf(shell_folder, hwndParent, cidl, apidl, &IID_IContextMenu, NULL, (LPVOID*)&pcm);
/* HRESULT hr = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &pcm); */
if (SUCCEEDED(hr)) {
CtxMenu_reset();
if (idCmd) {
- CMINVOKECOMMANDINFO cmi;
-
- cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
- cmi.fMask = 0;
- cmi.hwnd = hwndParent;
- cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - FCIDM_SHVIEWFIRST);
- cmi.lpParameters = NULL;
- cmi.lpDirectory = NULL;
- cmi.nShow = SW_SHOWNORMAL;
- cmi.dwHotKey = 0;
- cmi.hIcon = 0;
-
- hr = (*pcm->lpVtbl->InvokeCommand)(pcm, &cmi);
+ CMINVOKECOMMANDINFO cmi;
+
+ cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
+ cmi.fMask = 0;
+ cmi.hwnd = hwndParent;
+ cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - FCIDM_SHVIEWFIRST);
+ cmi.lpParameters = NULL;
+ cmi.lpDirectory = NULL;
+ cmi.nShow = SW_SHOWNORMAL;
+ cmi.dwHotKey = 0;
+ cmi.hIcon = 0;
+
+ hr = (*pcm->lpVtbl->InvokeCommand)(pcm, &cmi);
+ executed = TRUE;
}
} else
CtxMenu_reset();
}
- (*pcm->lpVtbl->Release)(pcm);
+ IUnknown_Release(pcm);
}
- return hr;
+ return FAILED(hr)? hr: executed? S_OK: S_FALSE;
}
-LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+static LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
- static int last_split;
-
- ChildWnd* child = (ChildWnd*) GetWindowLong(hwnd, GWL_USERDATA);
+ ChildWnd* child = (ChildWnd*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
ASSERT(child);
switch(nmsg) {
case WM_NCDESTROY:
free_child_window(child);
- SetWindowLong(hwnd, GWL_USERDATA, 0);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
break;
case WM_PAINT: {
#endif /* _NO_EXTENSIONS */
case WM_SETFOCUS:
- SetCurrentDirectory(child->path);
+ if (SetCurrentDirectory(child->path))
+ set_space_status();
SetFocus(child->focus_pane? child->right.hwnd: child->left.hwnd);
break;
break;}
case ID_REFRESH:
- scan_entry(child, pane->cur, hwnd);
+ refresh_drives();
+ refresh_child(child);
break;
case ID_ACTIVATE:
break;
case ID_FILE_MOVE: {
- TCHAR new_name[BUFFER_LEN], old_name[BUFFER_LEN];
- int len, ret;
+ TCHAR source[BUFFER_LEN], target[BUFFER_LEN];
- get_path(pane->cur, new_name);
+ if (prompt_target(pane, source, target)) {
+ SHFILEOPSTRUCT shfo = {hwnd, FO_MOVE, source, target};
- ret = DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_SELECT_DESTINATION), hwnd, DestinationDlgProc, (LPARAM)new_name);
- if (ret != IDOK)
- break;
+ source[lstrlen(source)+1] = '\0';
+ target[lstrlen(target)+1] = '\0';
+
+ if (!SHFileOperation(&shfo))
+ refresh_child(child);
+ }
+ break;}
+
+ case ID_FILE_COPY: {
+ TCHAR source[BUFFER_LEN], target[BUFFER_LEN];
- if (new_name[0]!='/' && new_name[1]!=':') {
- get_path(pane->cur->up, old_name);
- len = lstrlen(old_name);
+ if (prompt_target(pane, source, target)) {
+ SHFILEOPSTRUCT shfo = {hwnd, FO_COPY, source, target};
- if (old_name[len-1]!='\\' && old_name[len-1]!='/')
- old_name[len++] = '/';
+ source[lstrlen(source)+1] = '\0';
+ target[lstrlen(target)+1] = '\0';
- lstrcpy(old_name+len, new_name);
- lstrcpy(new_name, old_name);
+ if (!SHFileOperation(&shfo))
+ refresh_child(child);
}
+ break;}
- get_path(pane->cur, old_name);
+ case ID_FILE_DELETE: {
+ TCHAR path[BUFFER_LEN];
+ SHFILEOPSTRUCT shfo = {hwnd, FO_DELETE, path};
- if (MoveFileEx(old_name, new_name, MOVEFILE_COPY_ALLOWED)) {
- if (pane->treePane) {
- pane->root->scanned = FALSE;
- pane->cur = pane->root;
- activate_entry(child, pane, hwnd);
- }
- else
- scan_entry(child, pane->root, hwnd);
+ get_path(pane->cur, path);
+
+ path[lstrlen(path)+1] = '\0';
+
+ if (!SHFileOperation(&shfo))
+ refresh_child(child);
+ break;}
+
+ case ID_VIEW_SORT_NAME:
+ set_sort_order(child, SORT_NAME);
+ break;
+
+ case ID_VIEW_SORT_TYPE:
+ set_sort_order(child, SORT_EXT);
+ break;
+
+ case ID_VIEW_SORT_SIZE:
+ set_sort_order(child, SORT_SIZE);
+ break;
+
+ case ID_VIEW_SORT_DATE:
+ set_sort_order(child, SORT_DATE);
+ break;
+
+ case ID_VIEW_FILTER: {
+ struct FilterDialog dlg;
+
+ memset(&dlg, 0, sizeof(struct FilterDialog));
+ lstrcpy(dlg.pattern, child->filter_pattern);
+ dlg.flags = child->filter_flags;
+
+ if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE), hwnd, FilterDialogDlgProc, (LPARAM)&dlg) == IDOK) {
+ lstrcpy(child->filter_pattern, dlg.pattern);
+ child->filter_flags = dlg.flags;
+ refresh_right_pane(child);
}
- else
- display_error(hwnd, GetLastError());
break;}
+ case ID_VIEW_SPLIT: {
+ last_split = child->split_pos;
+#ifdef _NO_EXTENSIONS
+ draw_splitbar(hwnd, last_split);
+#endif
+ SetCapture(hwnd);
+ break;}
+
+ case ID_EDIT_PROPERTIES:
+ show_properties_dlg(pane->cur, child->hwnd);
+ break;
+
default:
return pane_command(pane, LOWORD(wparam));
}
Entry* entry = (Entry*) ListBox_GetItemData(pane->hwnd, idx);
if (pane == &child->left)
- set_curdir(child, entry, hwnd);
+ set_curdir(child, entry, idx, hwnd);
else
pane->cur = entry;
break;}
idx = ListBox_GetCurSel(pane->hwnd);
if (idx != -1) {
- HRESULT hr;
Entry* entry = (Entry*) ListBox_GetItemData(pane->hwnd, idx);
LPITEMIDLIST pidl_abs = get_to_absolute_pidl(entry, hwnd);
/* get and use the parent folder to display correct context menu in all cases */
if (SUCCEEDED(SHBindToParent(pidl_abs, &IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast))) {
- hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pt.x, pt.y);
+ if (ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pt.x, pt.y) == S_OK)
+ refresh_child(child);
- (*parentFolder->lpVtbl->Release)(parentFolder);
+ IShellFolder_Release(parentFolder);
}
- (*Globals.iMalloc->lpVtbl->Free)(Globals.iMalloc, pidl_abs);
+ IMalloc_Free(Globals.iMalloc, pidl_abs);
}
}
break;}
if (CtxMenu_HandleMenuMsg(nmsg, wparam, lparam))
return 0;
+ update_view_menu(child);
break;
#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
}
-LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+static LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
- ChildWnd* child = (ChildWnd*) GetWindowLong(GetParent(hwnd), GWL_USERDATA);
- Pane* pane = (Pane*) GetWindowLong(hwnd, GWL_USERDATA);
+ ChildWnd* child = (ChildWnd*) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+ Pane* pane = (Pane*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
ASSERT(child);
switch(nmsg) {
#endif
/* load column strings */
- col = 0;
+ col = 1;
load_string(g_pos_names[col++], IDS_COL_NAME);
load_string(g_pos_names[col++], IDS_COL_SIZE);
}
-void show_frame(HWND hwndParent, int cmdshow)
+static void show_frame(HWND hwndParent, int cmdshow, LPCTSTR path)
{
const static TCHAR sMDICLIENT[] = {'M','D','I','C','L','I','E','N','T','\0'};
- TCHAR path[MAX_PATH], b1[BUFFER_LEN];
+ TCHAR buffer[MAX_PATH], b1[BUFFER_LEN];
ChildWnd* child;
HMENU hMenuFrame, hMenuWindow;
if (Globals.hMainWnd)
return;
- Globals.hwndParent = hwndParent;
-
hMenuFrame = LoadMenu(Globals.hInstance, MAKEINTRESOURCE(IDM_WINEFILE));
hMenuWindow = GetSubMenu(hMenuFrame, GetMenuItemCount(hMenuFrame)-2);
Globals.hMainWnd, 0, Globals.hInstance, &ccs);
- {
- TBBUTTON drivebarBtn = {0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0};
- int btn = 1;
- PTSTR p;
-
- Globals.hdrivebar = CreateToolbarEx(Globals.hMainWnd, WS_CHILD|WS_VISIBLE|CCS_NOMOVEY|TBSTYLE_LIST,
- IDW_DRIVEBAR, 2, Globals.hInstance, IDB_DRIVEBAR, &drivebarBtn,
- 1, 16, 13, 16, 13, sizeof(TBBUTTON));
- CheckMenuItem(Globals.hMenuOptions, ID_VIEW_DRIVE_BAR, MF_BYCOMMAND|MF_CHECKED);
-
- GetLogicalDriveStrings(BUFFER_LEN, Globals.drives);
-
- drivebarBtn.fsStyle = BTNS_BUTTON;
+ CheckMenuItem(Globals.hMenuOptions, ID_VIEW_DRIVE_BAR, MF_BYCOMMAND|MF_CHECKED);
-#ifndef _NO_EXTENSIONS
-#ifdef __WINE__
- /* insert unix file system button */
- b1[0] = '/';
- b1[1] = '\0';
- b1[2] = '\0';
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b1);
-
- drivebarBtn.idCommand = ID_DRIVE_UNIX_FS;
- SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
- drivebarBtn.iString++;
-#endif
-#ifdef _SHELL_FOLDERS
- /* insert shell namespace button */
- load_string(b1, IDS_SHELL);
- b1[lstrlen(b1)+1] = '\0';
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b1);
-
- drivebarBtn.idCommand = ID_DRIVE_SHELL_NS;
- SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
- drivebarBtn.iString++;
-#endif
-
- /* register windows drive root strings */
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)Globals.drives);
-#endif
-
- drivebarBtn.idCommand = ID_DRIVE_FIRST;
-
- for(p=Globals.drives; *p; ) {
-#ifdef _NO_EXTENSIONS
- /* insert drive letter */
- TCHAR b[3] = {tolower(*p)};
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)b);
-#endif
- switch(GetDriveType(p)) {
- case DRIVE_REMOVABLE: drivebarBtn.iBitmap = 1; break;
- case DRIVE_CDROM: drivebarBtn.iBitmap = 3; break;
- case DRIVE_REMOTE: drivebarBtn.iBitmap = 4; break;
- case DRIVE_RAMDISK: drivebarBtn.iBitmap = 5; break;
- default:/*DRIVE_FIXED*/ drivebarBtn.iBitmap = 2;
- }
-
- SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
- drivebarBtn.idCommand++;
- drivebarBtn.iString++;
-
- while(*p++);
- }
- }
+ create_drive_bar();
{
TBBUTTON toolbarBtns[] = {
Globals.hMainWnd, (HMENU)IDW_STATUSBAR, hinstance, 0);*/
/*TODO: read paths and window placements from registry */
- GetCurrentDirectory(MAX_PATH, path);
+
+ if (!path || !*path) {
+ GetCurrentDirectory(MAX_PATH, buffer);
+ path = buffer;
+ }
ShowWindow(Globals.hMainWnd, cmdshow);
UpdateWindow(Globals.hMainWnd);
}
-void ExitInstance()
+static void ExitInstance(void)
{
#ifdef _SHELL_FOLDERS
- (*Globals.iDesktop->lpVtbl->Release)(Globals.iDesktop);
- (*Globals.iMalloc->lpVtbl->Release)(Globals.iMalloc);
+ IShellFolder_Release(Globals.iDesktop);
+ IMalloc_Release(Globals.iMalloc);
CoUninitialize();
#endif
+ DeleteObject(Globals.hfont);
ImageList_Destroy(Globals.himl);
}
+#ifdef _NO_EXTENSIONS
/* search for already running win[e]files */
}
/* search for window of given class name to allow only one running instance */
-int find_window_class(LPCTSTR classname)
+static int find_window_class(LPCTSTR classname)
{
EnumWindows(EnumWndProc, (LPARAM)classname);
return 0;
}
+#endif
-int winefile_main(HINSTANCE hinstance, HWND hwndParent, int cmdshow)
+static int winefile_main(HINSTANCE hinstance, int cmdshow, LPCTSTR path)
{
MSG msg;
/*TODO: read window placement from registry */
cmdshow = SW_MAXIMIZE;
- show_frame(hwndParent, cmdshow);
+ show_frame(0, cmdshow, path);
while(GetMessage(&msg, 0, 0, 0)) {
if (Globals.hmdiclient && TranslateMDISysAccel(Globals.hmdiclient, &msg))
}
-int APIENTRY WinMain(HINSTANCE hinstance,
- HINSTANCE previnstance,
- LPSTR cmdline,
- int cmdshow)
+#if defined(UNICODE) && defined(_MSC_VER)
+int APIENTRY wWinMain(HINSTANCE hinstance, HINSTANCE previnstance, LPWSTR cmdline, int cmdshow)
+#else
+int APIENTRY WinMain(HINSTANCE hinstance, HINSTANCE previnstance, LPSTR cmdline, int cmdshow)
+#endif
{
#ifdef _NO_EXTENSIONS
if (find_window_class(sWINEFILEFRAME))
return 1;
#endif
- winefile_main(hinstance, 0, cmdshow);
+#if defined(UNICODE) && !defined(_MSC_VER)
+ { /* convert ANSI cmdline into WCS path string */
+ TCHAR buffer[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, cmdline, -1, buffer, MAX_PATH);
+ winefile_main(hinstance, cmdshow, buffer);
+ }
+#else
+ winefile_main(hinstance, cmdshow, cmdline);
+#endif
return 0;
}