/*
* Winefile
*
- * Copyright 2000, 2003, 2004 Martin Fuchs
+ * Copyright 2000, 2003, 2004, 2005 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _WIN32
+#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
-#include <locale.h>
+#define COBJMACROS
#include "winefile.h"
-#include "resource.h"
-
-#ifdef _ROS_
-#include "externals.h"
-#endif
+#include "resource.h"
-/* for read_directory_unix() */
-#if !defined(_NO_EXTENSIONS) && !defined(_WIN32)
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-#endif
#ifdef _NO_EXTENSIONS
#undef _LEFT_FILES
#define _MAX_PATH 260
#endif
-#ifdef __linux__
-#define UNION_MEMBER(x) DUMMYUNIONNAME.##x
+#ifdef NONAMELESSUNION
+#define UNION_MEMBER(x) DUMMYUNIONNAME.x
#else
#define UNION_MEMBER(x) x
#endif
#endif
-WINEFILE_GLOBALS Globals;
-
-extern void WineLicense(HWND hwnd);
-extern void WineWarranty(HWND hwnd);
-
enum ENTRY_TYPE {
ET_WINDOWS,
ET_UNIX,
BOOL header_wdths_ok;
TCHAR path[MAX_PATH];
+ TCHAR filter_pattern[MAX_PATH];
+ int filter_flags;
Root root;
SORT_ORDER sortOrder;
} ChildWnd;
+
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);
+
+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'};
+const static TCHAR sSpace[] = {' ', '\0'};
+const static TCHAR sNumFmt[] = {'%','d','\0'};
+const static TCHAR sQMarks[] = {'?','?','?','\0'};
+
+/* window class names */
+const static TCHAR sWINEFILEFRAME[] = {'W','F','S','_','F','r','a','m','e','\0'};
+const static TCHAR sWINEFILETREE[] = {'W','F','S','_','T','r','e','e','\0'};
+
+#ifdef _MSC_VER
+/* #define LONGLONGARG _T("I64") */
+const static TCHAR sLongHexFmt[] = {'%','I','6','4','X','\0'};
+const static TCHAR sLongNumFmt[] = {'%','I','6','4','d','\0'};
+#else
+/* #define LONGLONGARG _T("L") */
+const static TCHAR sLongHexFmt[] = {'%','L','X','\0'};
+const static TCHAR sLongNumFmt[] = {'%','L','d','\0'};
+#endif
-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);
+
+/* load resource string */
+static LPTSTR load_string(LPTSTR buffer, UINT id)
+{
+ LoadString(Globals.hInstance, id, buffer, BUFFER_LEN);
+
+ return buffer;
+}
+
+#define RS(b, i) load_string(b, i)
/* display error message for the specified WIN32 error code */
static void display_error(HWND hwnd, DWORD error)
{
+ TCHAR b1[BUFFER_LEN], b2[BUFFER_LEN];
PTSTR msg;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PTSTR)&msg, 0, NULL))
- MessageBox(hwnd, msg, TEXT("Winefile"), MB_OK);
+ MessageBox(hwnd, msg, RS(b2,IDS_WINEFILE), MB_OK);
else
- MessageBox(hwnd, TEXT("Error"), TEXT("Winefile"), MB_OK);
+ MessageBox(hwnd, RS(b1,IDS_ERROR), RS(b2,IDS_WINEFILE), MB_OK);
LocalFree(msg);
}
+/* 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);
for(p=buffer; *path; )
*p++ = *path++;
- lstrcpy(p, TEXT("\\*"));
+ *p++ = '\\';
+ p[0] = '*';
+ p[1] = '\0';
hFind = FindFirstFile(buffer, &w32fd);
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;
- lstrcpy(p+1, entry->data.cFileName);
+ lstrcpy(p, entry->data.cFileName);
hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
#endif
last = entry;
- } while(FindNextFile(hFind, &entry->data));
+ } while(FindNextFile(hFind, &w32fd));
- last->next = NULL;
+ if (last)
+ last->next = NULL;
FindClose(hFind);
}
}
-#if !defined(_NO_EXTENSIONS) && defined(__linux__)
+#if !defined(_NO_EXTENSIONS) && defined(__WINE__)
+
+static BOOL time_to_filetime(const time_t* t, FILETIME* ftime)
+{
+ struct tm* tm = gmtime(t);
+ SYSTEMTIME stime;
+
+ if (!tm)
+ return FALSE;
+
+ stime.wYear = tm->tm_year+1900;
+ stime.wMonth = tm->tm_mon+1;
+ /* stime.wDayOfWeek */
+ stime.wDay = tm->tm_mday;
+ stime.wHour = tm->tm_hour;
+ stime.wMinute = tm->tm_min;
+ stime.wSecond = tm->tm_sec;
+
+ return SystemTimeToFileTime(&stime, ftime);
+}
static void read_directory_unix(Entry* dir, LPCTSTR path)
{
Entry* first_entry = NULL;
Entry* last = NULL;
Entry* entry;
+ DIR* pdir;
int level = dir->level + 1;
+#ifdef UNICODE
+ char cpath[MAX_PATH];
- DIR* pdir = opendir(path);
+ WideCharToMultiByte(CP_UNIXCP, 0, path, -1, cpath, MAX_PATH, NULL, NULL);
+#else
+ const char* cpath = path;
+#endif
+
+ pdir = opendir(cpath);
if (pdir) {
struct stat st;
struct dirent* ent;
- TCHAR buffer[MAX_PATH], *p;
+ char buffer[MAX_PATH], *p;
+ const char* s;
- for(p=buffer; *path; )
- *p++ = *path++;
+ for(p=buffer,s=cpath; *s; )
+ *p++ = *s++;
if (p==buffer || p[-1]!='/')
*p++ = '/';
entry->etype = ET_UNIX;
- lstrcpy(entry->data.cFileName, ent->d_name);
- entry->data.dwFileAttributes = ent->d_name[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
-
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
if (!stat(buffer, &st)) {
+ entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0;
+
if (S_ISDIR(st.st_mode))
entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
last = entry;
}
- last->next = NULL;
+ if (last)
+ last->next = NULL;
closedir(pdir);
}
return entry;
}
-#endif // !defined(_NO_EXTENSIONS) && defined(__linux__)
+#endif /* !defined(_NO_EXTENSIONS) && defined(__WINE__) */
#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);
+ /* SHGDN_FORPARSING: get full path of id list */
+ 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;
}
-static Entry* find_entry_shell(Entry* dir, LPITEMIDLIST pidl)
+static Entry* find_entry_shell(Entry* dir, LPCITEMIDLIST pidl)
{
Entry* entry;
if (!pidl->mkid.cb)
break;
- // copy first element of item idlist -> could be replaced by SHBindToParent()
- next_pidl = (*Globals.iMalloc->lpVtbl->Alloc)(Globals.iMalloc, pidl->mkid.cb+sizeof(USHORT));
+ /* copy first element of item idlist */
+ 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;
folder = child;
entry = next;
- // go to next element
+ /* go to next element */
pidl = (LPITEMIDLIST) ((LPBYTE)pidl+pidl->mkid.cb);
}
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;
memset(&entry->data, 0, sizeof(WIN32_FIND_DATA));
entry->bhfi_valid = FALSE;
- attribs = ~SFGAO_FILESYSTEM; //SFGAO_HASSUBFOLDER|SFGAO_FOLDER; SFGAO_FILESYSTEM sorgt dafür, daß "My Documents" anstatt von "Martin's Documents" angezeigt wird
+ 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)
dir->scanned = TRUE;
}
-#endif // _SHELL_FOLDERS
+#endif /* _SHELL_FOLDERS */
/* sort order for different directory/file types */
}
/* 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 = &(*(Entry**)arg1)->data;
- const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
+ const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
+ const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
int cmp = compareType(fd1, fd2);
if (cmp)
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 = &(*(Entry**)arg1)->data;
- const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
+ const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
+ const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
const TCHAR *name1, *name2, *ext1, *ext2;
int cmp = compareType(fd1, fd2);
if (ext1)
ext1++;
else
- ext1 = TEXT("");
+ ext1 = sEmpty;
if (ext2)
ext2++;
else
- ext2 = TEXT("");
+ ext2 = sEmpty;
cmp = lstrcmpi(ext1, ext2);
if (cmp)
return lstrcmpi(name1, name2);
}
-static int compareSize(const void* arg1, const void* arg2)
+static int __cdecl compareSize(const void* arg1, const void* arg2)
{
- WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
- WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
+ const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
+ const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
int cmp = compareType(fd1, fd2);
if (cmp)
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)
{
- WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
- WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
+ const WIN32_FIND_DATA* fd1 = &(*(const Entry* const*)arg1)->data;
+ const WIN32_FIND_DATA* fd2 = &(*(const Entry* const*)arg2)->data;
int cmp = compareType(fd1, fd2);
if (cmp)
}
-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**) alloca(len*sizeof(Entry*));
+ array = HeapAlloc(GetProcessHeap(), 0, len*sizeof(Entry*));
p = array;
for(entry=dir->down; entry; entry=entry->next)
p[0]->next = p[1];
(*p)->next = 0;
+
+ HeapFree(GetProcessHeap(), 0, array);
}
}
}
else
#endif
-#if !defined(_NO_EXTENSIONS) && defined(__linux__)
+#if !defined(_NO_EXTENSIONS) && defined(__WINE__)
if (dir->etype == ET_UNIX)
{
read_directory_unix(dir, path);
}
+static Entry* read_tree(Root* root, LPCTSTR path, LPITEMIDLIST pidl, LPTSTR drv, SORT_ORDER sortOrder, HWND hwnd)
+{
+#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;
Entry* entry;
_tsplitpath(path, drv, dir, name, ext);
}
- root->entry.level = 0;
-
-#ifdef _SHELL_FOLDERS
- if (pidl)
- {
- root->drive_type = DRIVE_UNKNOWN;
- lstrcpy(drv, TEXT("\\"));
- lstrcpy(root->volname, TEXT("Desktop"));
- root->fs_flags = 0;
- lstrcpy(root->fs, TEXT("Shell"));
-
- entry = read_tree_shell(root, pidl, child->sortOrder, hwnd);
- }
- else
-#endif
-#if !defined(_NO_EXTENSIONS) && defined(__linux__)
- if (*path == '/')
- {
- root->drive_type = GetDriveType(path);
-
- lstrcat(drv, TEXT("/"));
- lstrcpy(root->volname, TEXT("root fs"));
- root->fs_flags = 0;
- lstrcpy(root->fs, TEXT("unixfs"));
-
- lstrcpy(root->path, TEXT("/"));
- 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, TEXT("\\"));
- 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)
- lstrcpy(root->entry.data.cFileName, TEXT("Desktop"));
+ load_string(root->entry.data.cFileName, IDS_DESKTOP);
else
#endif
- wsprintf(root->entry.data.cFileName, TEXT("%s - %s"), drv, root->fs);
+ wsprintf(root->entry.data.cFileName, RS(b1,IDS_TITLEFMT), drv, root->fs);
root->entry.data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
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);
MDICREATESTRUCT mcs;
int idx;
- mcs.szClass = WINEFILETREE;
+ mcs.szClass = sWINEFILETREE;
mcs.szTitle = (LPTSTR)child->path;
mcs.hOwner = Globals.hInstance;
mcs.x = child->pos.rcNormalPosition.left;
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 BOOL CALLBACK ExecuteDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+static INT_PTR CALLBACK ExecuteDialogDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
{
static struct ExecuteDialog* dlg;
return 0;
}
-static BOOL CALLBACK sDestinationDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+
+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;
case WM_COMMAND: {
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;}
break;
case 254:
- MessageBox(hwnd, TEXT("Not yet implemented"), TEXT("Winefile"), MB_OK);
+ MessageBox(hwnd, RS(b1,IDS_NO_IMPL), RS(b2,IDS_WINEFILE), MB_OK);
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];
+
switch(nmsg) {
case WM_CLOSE:
DestroyWindow(hwnd);
- // clear handle variables
+ /* clear handle variables */
Globals.hMenuFrame = 0;
Globals.hMenuView = 0;
Globals.hMenuOptions = 0;
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;
case ID_WINDOW_ARRANGE:
SendMessage(Globals.hmdiclient, WM_MDIICONARRANGE, 0, 0);
break;
-
+
case ID_SELECT_FONT: {
TCHAR dlg_name[BUFFER_LEN], dlg_info[BUFFER_LEN];
CHOOSEFONT chFont;
if (ChooseFont(&chFont)) {
HWND childWnd;
+ HFONT hFontOld;
+ DeleteObject(Globals.hfont);
Globals.hfont = CreateFontIndirect(&lFont);
- SelectFont(hdc, Globals.hfont);
- GetTextExtentPoint32(hdc, TEXT(" "), 1, &Globals.spaceSize);
+ 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));
+ ListBox_SetItemHeight(child->right.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: {
+ 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;}
+
+#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, TEXT("winfile"), HELP_INDEX, 0);
+ WinHelp(hwnd, RS(b1,IDS_WINEFILE), HELP_INDEX, 0);
break;
#ifndef _NO_EXTENSIONS
CheckMenuItem(Globals.hMenuOptions, cmd, toggle_fullscreen(hwnd)?MF_CHECKED:0);
break;
-#ifdef __linux__
+#ifdef __WINE__
case ID_DRIVE_UNIX_FS: {
TCHAR path[MAX_PATH];
+#ifdef UNICODE
+ char cpath[MAX_PATH];
+#endif
ChildWnd* child;
- if (activate_fs_window(TEXT("unixfs")))
+ if (activate_fs_window(RS(b1,IDS_UNIXFS)))
break;
+
+#ifdef UNICODE
+ getcwd(cpath, MAX_PATH);
+ MultiByteToWideChar(CP_UNIXCP, 0, cpath, -1, path, MAX_PATH);
+#else
getcwd(path, MAX_PATH);
+#endif
child = alloc_child_window(path, NULL, hwnd);
if (!create_child_window(child))
free(child);
break;}
#endif
+
#ifdef _SHELL_FOLDERS
case ID_DRIVE_SHELL_NS: {
TCHAR path[MAX_PATH];
ChildWnd* child;
- if (activate_fs_window(TEXT("Shell")))
+ if (activate_fs_window(RS(b1,IDS_SHELL)))
break;
GetCurrentDirectory(MAX_PATH, path);
case ID_NO_WARRANTY:
WineWarranty(Globals.hMainWnd);
break;
-#endif
case ID_ABOUT_WINE:
- ShellAbout(hwnd, TEXT("WINE"), TEXT("Winefile"), 0);
+ ShellAbout(hwnd, RS(b2,IDS_WINE), RS(b1,IDS_WINEFILE), 0);
break;
+#endif
- case ID_ABOUT: //ID_ABOUT_WINE:
- ShellAbout(hwnd, TEXT("Winefile"), NULL, 0);
+ case ID_ABOUT:
+ ShellAbout(hwnd, RS(b1,IDS_WINEFILE), NULL, 0);
break;
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
default:
/*TODO: if (wParam >= PM_FIRST_LANGUAGE && wParam <= PM_LAST_LANGUAGE)
STRING_SelectLanguageByNumber(wParam - PM_FIRST_LANGUAGE);
else */if ((cmd<IDW_FIRST_CHILD || cmd>=IDW_FIRST_CHILD+0x100) &&
(cmd<SC_SIZE || cmd>SC_RESTORE))
- MessageBox(hwnd, TEXT("Not yet implemented"), TEXT("Winefile"), MB_OK);
+ MessageBox(hwnd, RS(b2,IDS_NO_IMPL), RS(b1,IDS_WINEFILE), MB_OK);
return DefFrameProc(hwnd, Globals.hmdiclient, nmsg, wparam, lparam);
}
case FRM_CALC_CLIENT:
frame_get_clientspace(hwnd, (PRECT)lparam);
return TRUE;
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
default:
return DefFrameProc(hwnd, Globals.hmdiclient, nmsg, wparam, lparam);
}
-static const LPTSTR g_pos_names[COLUMNS] = {
- TEXT(""), /* symbol */
- TEXT("Name"),
- TEXT("Size"),
- TEXT("CDate"),
-#ifndef _NO_EXTENSIONS
- TEXT("ADate"),
- TEXT("MDate"),
- TEXT("Index/Inode"),
- TEXT("Links"),
-#endif // _NO_EXTENSIONS
- TEXT("Attributes"),
-#ifndef _NO_EXTENSIONS
- TEXT("Security")
-#endif
+static TCHAR g_pos_names[COLUMNS][20] = {
+ {'\0'} /* symbol */
};
static const int g_pos_align[] = {
DeferWindowPos(hdwp, child->right.hwndHeader, wp.hwndInsertAfter,
rt.left+cx+1, wp.y, wp.cx-cx+2, wp.cy, wp.flags);
}
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
DeferWindowPos(hdwp, child->left.hwnd, 0, rt.left, rt.top, child->split_pos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, child->right.hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
return hwnd;
}
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
static void init_output(HWND hwnd)
{
+ const static TCHAR s1000[] = {'1','0','0','0','\0'};
+
TCHAR b[16];
HFONT old_font;
HDC hdc = GetDC(hwnd);
- if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4)
+ if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, s1000, 0, b, 16) > 4)
Globals.num_sep = b[1];
else
Globals.num_sep = TEXT('.');
old_font = SelectFont(hdc, Globals.hfont);
- GetTextExtentPoint32(hdc, TEXT(" "), 1, &Globals.spaceSize);
+ GetTextExtentPoint32(hdc, sSpace, 1, &Globals.spaceSize);
SelectFont(hdc, old_font);
ReleaseDC(hwnd, hdc);
}
static void draw_item(Pane* pane, LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol);
-/* calculate prefered width for all visible columns */
+/* calculate preferred width for all visible columns */
static BOOL calc_widths(Pane* pane, BOOL anyway)
{
}
-/* calculate one prefered column width */
+/* calculate one preferred column width */
static void calc_single_width(Pane* pane, int col)
{
}
+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 void 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;
if (!entry)
- return;
+ return idx;
ShowWindow(pane->hwnd, SW_HIDE);
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)
- insert_entries(pane, entry->down, idx);
+ idx = insert_entries(pane, entry->down, pattern, filter_flags, idx);
}
- ShowWindow(pane->hwnd, SW_SHOW);
+ ShowWindow(pane->hwnd, SW_SHOW);
+
+ return idx;
+}
+
+
+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'};
+
static int s_init = 0;
Entry* entry = pane->root;
- pane->hwnd = CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
+ pane->hwnd = CreateWindow(sListBox, sEmpty, WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
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,TEXT("???")); 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 LPCTSTR executable_extensions[] = {
- TEXT("COM"),
- TEXT("EXE"),
- TEXT("BAT"),
- TEXT("CMD"),
+ static const TCHAR executable_extensions[][4] = {
+ {'C','O','M','\0'},
+ {'E','X','E','\0'},
+ {'B','A','T','\0'},
+ {'C','M','D','\0'},
#ifndef _NO_EXTENSIONS
- TEXT("CMM"),
- TEXT("BTM"),
- TEXT("AWK"),
-#endif // _NO_EXTENSIONS
- 0
+ {'C','M','M','\0'},
+ {'B','T','M','\0'},
+ {'A','W','K','\0'},
+#endif /* _NO_EXTENSIONS */
+ {'\0'}
};
TCHAR ext_buffer[_MAX_EXT];
- const LPCTSTR* p;
+ const TCHAR (*p)[4];
LPCTSTR s;
LPTSTR d;
for(s=ext+1,d=ext_buffer; (*d=tolower(*s)); s++)
d++;
- for(p=executable_extensions; *p; p++)
- if (!_tcscmp(ext_buffer, *p))
- return 1;
+ for(p=executable_extensions; (*p)[0]; p++)
+ 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 FALSE;
+}
- return 1;
+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 = TEXT("");
-
- 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;
if (pane->treePane) {
if (entry) {
- img_pos = dis->rcItem.left + entry->level*(IMAGE_WIDTH+Globals.spaceSize.cx);
+ img_pos = dis->rcItem.left + entry->level*(IMAGE_WIDTH+TREE_LINE_DX);
if (calcWidthCol == -1) {
int x;
x = img_pos - IMAGE_WIDTH/2;
do {
- x -= IMAGE_WIDTH+Globals.spaceSize.cx;
+ x -= IMAGE_WIDTH+TREE_LINE_DX;
if (up->next
#ifndef _LEFT_FILES
)
LineTo(dis->hDC, x, dis->rcItem.bottom);
- if (entry->down && entry->expanded) {
- x += IMAGE_WIDTH+Globals.spaceSize.cx;
- 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); */
} else if (calcWidthCol==col || calcWidthCol==COLUMNS) {
- int right = img_pos + IMAGE_WIDTH - Globals.spaceSize.cx;
+ int right = img_pos + IMAGE_WIDTH - TREE_LINE_DX;
if (right > pane->widths[col])
pane->widths[col] = right;
DrawText(dis->hDC, entry->data.cFileName, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX);
- focusRect.right = dis->rcItem.left+pane->positions[col+1]+Globals.spaceSize.cx + rt.right +2;
+ focusRect.right = dis->rcItem.left+pane->positions[col+1]+TREE_LINE_DX + rt.right +2;
}
#else
if (attrs & FILE_ATTRIBUTE_COMPRESSED)
textcolor = COLOR_COMPRESSED;
else
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
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);
{
ULONGLONG size;
- size = ((ULONGLONG)entry->data.nFileSizeHigh << 32) | entry->data.nFileSizeLow;
+ size = ((ULONGLONG)entry->data.nFileSizeHigh << 32) | entry->data.nFileSizeLow;
- _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size);
+ _stprintf(buffer, sLongNumFmt, size);
if (calcWidthCol == -1)
output_number(pane, dis, col, buffer);
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
calc_width(pane, dis, col, buffer);
col++;
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
format_date(&entry->data.ftLastWriteTime, buffer, visible_cols);
if (calcWidthCol == -1)
ULONGLONG index = ((ULONGLONG)entry->bhfi.nFileIndexHigh << 32) | entry->bhfi.nFileIndexLow;
if (visible_cols & COL_INDEX) {
- _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index);
+ _stprintf(buffer, sLongHexFmt, index);
+
if (calcWidthCol == -1)
output_text(pane, dis, col, buffer, DT_RIGHT);
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
calc_width(pane, dis, col, buffer);
+
col++;
}
if (visible_cols & COL_LINKS) {
- wsprintf(buffer, TEXT("%d"), entry->bhfi.nNumberOfLinks);
+ wsprintf(buffer, sNumFmt, entry->bhfi.nNumberOfLinks);
+
if (calcWidthCol == -1)
output_text(pane, dis, col, buffer, DT_CENTER);
else if (calcWidthCol==col || calcWidthCol==COLUMNS)
calc_width(pane, dis, col, buffer);
+
col++;
}
} else
col += 2;
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
/* show file attributes */
if (visible_cols & COL_ATTRIBUTES) {
#ifdef _NO_EXTENSIONS
- _tcscpy(buffer, TEXT(" \t \t \t \t "));
+ const static TCHAR s4Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
+ lstrcpy(buffer, s4Tabs);
#else
- _tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
+ const static TCHAR s11Tabs[] = {' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\t',' ','\0'};
+ lstrcpy(buffer, s11Tabs);
#endif
if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N';
if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) buffer[20] = 'Q';
if (attrs & FILE_ATTRIBUTE_OFFLINE) buffer[22] = 'O';
if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) buffer[24] = 'X';
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
}
if (calcWidthCol == -1)
/*TODO
if (flags.security) {
+ const static TCHAR sSecTabs[] = {
+ ' ','\t',' ','\t',' ','\t',' ',
+ ' ','\t',' ',
+ ' ','\t',' ','\t',' ','\t',' ',
+ ' ','\t',' ',
+ ' ','\t',' ','\t',' ','\t',' ',
+ '\0'
+ };
+
DWORD rights = get_access_mask();
- tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
+ 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
SelectObject(dis->hDC, lastPen);
DeleteObject(hpen);
}
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
}
ReleaseDC(hwnd, hdc);
}
-#endif // _NO_EXTENSIONS
+#endif /* _NO_EXTENSIONS */
#ifndef _NO_EXTENSIONS
RECT clnt;
GetClientRect(pane->hwnd, &clnt);
- /* move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB) */
+ /* move immediate to simulate HDS_FULLDRAG (for now [04/2000] not really needed with WINELIB) */
Header_SetItem(pane->hwndHeader, idx, phdn->pitem);
pane->widths[idx] += dx;
return 0;
}
-#endif // _NO_EXTENSIONS
+#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);
}
}
break;
#ifndef _NO_EXTENSIONS
- case ID_PREFERED_SIZES: {
+ case ID_PREFERRED_SIZES: {
calc_widths(pane, TRUE);
set_header(pane);
InvalidateRect(pane->hwnd, 0, TRUE);
}
+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(void)
+{
+ s_pctxmenu2 = NULL;
+
+#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
+ s_pctxmenu3 = NULL;
+#endif
+}
+
+static IContextMenu* CtxMenu_query_interfaces(IContextMenu* pcm1)
+{
+ IContextMenu* pcm = NULL;
+
+ CtxMenu_reset();
+
+#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
+ if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu3, (void**)&pcm) == NOERROR)
+ s_pctxmenu3 = (LPCONTEXTMENU3)pcm;
+ else
+#endif
+ if (IUnknown_QueryInterface(pcm1, &IID_IContextMenu2, (void**)&pcm) == NOERROR)
+ s_pctxmenu2 = (LPCONTEXTMENU2)pcm;
+
+ if (pcm) {
+ IUnknown_Release(pcm1);
+ return pcm;
+ } else
+ return pcm1;
+}
+
+static BOOL CtxMenu_HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
+ if (s_pctxmenu3) {
+ if (SUCCEEDED((*s_pctxmenu3->lpVtbl->HandleMenuMsg)(s_pctxmenu3, nmsg, wparam, lparam)))
+ return TRUE;
+ }
+#endif
+
+ if (s_pctxmenu2)
+ if (SUCCEEDED((*s_pctxmenu2->lpVtbl->HandleMenuMsg)(s_pctxmenu2, nmsg, wparam, lparam)))
+ return TRUE;
+
+ return FALSE;
+}
+
+
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 = CDefFolderMenu_Create2(dir?dir->_pidl:DesktopFolder(), hwndParent, 1, &pidl, shell_folder, NULL, 0, NULL, &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)) {
HMENU hmenu = CreatePopupMenu();
+ pcm = CtxMenu_query_interfaces(pcm);
+
if (hmenu) {
hr = (*pcm->lpVtbl->QueryContextMenu)(pcm, hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
if (SUCCEEDED(hr)) {
UINT idCmd = TrackPopupMenu(hmenu, TPM_LEFTALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, x, y, 0, hwndParent, NULL);
+ 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) {
if (dis->CtlID == IDW_TREE_LEFT)
draw_item(&child->left, dis, entry, -1);
- else
+ else if (dis->CtlID == IDW_TREE_RIGHT)
draw_item(&child->right, dis, entry, -1);
+ else
+ goto draw_menu_item;
return TRUE;}
case WM_NCDESTROY:
free_child_window(child);
- SetWindowLong(hwnd, GWL_USERDATA, 0);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
break;
case WM_PAINT: {
lpmmi->ptMaxTrackSize.x <<= 1;/*2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN */
lpmmi->ptMaxTrackSize.y <<= 1;/*2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN */
break;}
-#endif // _NO_EXTENSIONS
+#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;
+ TCHAR source[BUFFER_LEN], target[BUFFER_LEN];
- int ret = DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_SELECT_DESTINATION), hwnd, sDestinationDlgProc, (LPARAM)new_name);
- if (ret != IDOK)
- break;
+ if (prompt_target(pane, source, target)) {
+ SHFILEOPSTRUCT shfo = {hwnd, FO_MOVE, source, target};
- if (new_name[0]!='/' && new_name[1]!=':') {
- get_path(pane->cur->up, old_name);
- len = lstrlen(old_name);
+ source[lstrlen(source)+1] = '\0';
+ target[lstrlen(target)+1] = '\0';
- if (old_name[len-1]!='\\' && old_name[len-1]!='/') {
- old_name[len++] = '/';
- old_name[len] = '\n';
- }
+ if (!SHFileOperation(&shfo))
+ refresh_child(child);
+ }
+ break;}
- lstrcpy(&old_name[len], new_name);
- lstrcpy(new_name, old_name);
+ case ID_FILE_COPY: {
+ TCHAR source[BUFFER_LEN], target[BUFFER_LEN];
+
+ if (prompt_target(pane, source, target)) {
+ SHFILEOPSTRUCT shfo = {hwnd, FO_COPY, source, target};
+
+ source[lstrlen(source)+1] = '\0';
+ target[lstrlen(target)+1] = '\0';
+
+ 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;}
#ifdef _SHELL_FOLDERS
case WM_CONTEXTMENU: {
+ POINT pt, pt_clnt;
Pane* pane;
int idx;
- // first select the current item in the listbox
+ /* first select the current item in the listbox */
HWND hpanel = (HWND) wparam;
- POINTS* ppos = &MAKEPOINTS(lparam);
- POINT pt; POINTSTOPOINT(pt, *ppos);
- ScreenToClient(hpanel, &pt);
- SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y));
- SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt.x, pt.y));
+ pt_clnt.x = pt.x = (short)LOWORD(lparam);
+ pt_clnt.y = pt.y = (short)HIWORD(lparam);
+ ScreenToClient(hpanel, &pt_clnt);
+ SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt_clnt.x, pt_clnt.y));
+ SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt_clnt.x, pt_clnt.y));
- // now create the popup menu using shell namespace and IContextMenu
+ /* now create the popup menu using shell namespace and IContextMenu */
pane = GetFocus()==child->left.hwnd? &child->left: &child->right;
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);
IShellFolder* parentFolder;
LPCITEMIDLIST pidlLast;
- // get and use the parent folder to display correct context menu in all cases
+ /* 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, ppos->x, ppos->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;}
#endif
+ case WM_MEASUREITEM:
+ draw_menu_item:
+ if (!wparam) /* Is the message menu-related? */
+ if (CtxMenu_HandleMenuMsg(nmsg, wparam, lparam))
+ return TRUE;
+
+ break;
+
+ case WM_INITMENUPOPUP:
+ if (CtxMenu_HandleMenuMsg(nmsg, wparam, lparam))
+ return 0;
+
+ update_view_menu(child);
+ break;
+
+#ifndef __MINGW32__ /* IContextMenu3 missing in MinGW (as of 6.2.2005) */
+ case WM_MENUCHAR: /* only supported by IContextMenu3 */
+ if (s_pctxmenu3) {
+ LRESULT lResult = 0;
+
+ (*s_pctxmenu3->lpVtbl->HandleMenuMsg2)(s_pctxmenu3, nmsg, wparam, lparam, &lResult);
+
+ return lResult;
+ }
+
+ break;
+#endif
+
case WM_SIZE:
if (wparam != SIZE_MINIMIZED)
resize_tree(child, LOWORD(lparam), HIWORD(lparam));
}
-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) {
static void InitInstance(HINSTANCE hinstance)
{
+ const static TCHAR sFont[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
+
WNDCLASSEX wcFrame;
WNDCLASS wcChild;
ATOM hChildClass;
+ int col;
INITCOMMONCONTROLSEX icc = {
sizeof(INITCOMMONCONTROLSEX),
HDC hdc = GetDC(0);
- setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName
+ setlocale(LC_COLLATE, ""); /* set collating rules to local settings for compareName */
InitCommonControlsEx(&icc);
wcFrame.hCursor = LoadCursor(0, IDC_ARROW);
wcFrame.hbrBackground = 0;
wcFrame.lpszMenuName = 0;
- wcFrame.lpszClassName = WINEFILEFRAME;
+ wcFrame.lpszClassName = sWINEFILEFRAME;
wcFrame.hIconSm = (HICON)LoadImage(hinstance,
MAKEINTRESOURCE(IDI_WINEFILE),
IMAGE_ICON,
wcChild.hCursor = LoadCursor(0, IDC_ARROW);
wcChild.hbrBackground = 0;
wcChild.lpszMenuName = 0;
- wcChild.lpszClassName = WINEFILETREE;
+ wcChild.lpszClassName = sWINEFILETREE;
hChildClass = RegisterClass(&wcChild);
Globals.haccel = LoadAccelerators(hinstance, MAKEINTRESOURCE(IDA_WINEFILE));
- Globals.hfont = CreateFont(-MulDiv(8,GetDeviceCaps(hdc,LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans Serif"));
+ Globals.hfont = CreateFont(-MulDiv(8,GetDeviceCaps(hdc,LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sFont);
ReleaseDC(0, hdc);
CoInitialize(NULL);
CoGetMalloc(MEMCTX_TASK, &Globals.iMalloc);
SHGetDesktopFolder(&Globals.iDesktop);
+#ifdef __WINE__
+ Globals.cfStrFName = RegisterClipboardFormatA(CFSTR_FILENAME);
+#else
Globals.cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME);
#endif
+#endif
+
+ /* load column strings */
+ col = 1;
+
+ load_string(g_pos_names[col++], IDS_COL_NAME);
+ load_string(g_pos_names[col++], IDS_COL_SIZE);
+ load_string(g_pos_names[col++], IDS_COL_CDATE);
+#ifndef _NO_EXTENSIONS
+ load_string(g_pos_names[col++], IDS_COL_ADATE);
+ load_string(g_pos_names[col++], IDS_COL_MDATE);
+ load_string(g_pos_names[col++], IDS_COL_IDX);
+ load_string(g_pos_names[col++], IDS_COL_LINKS);
+#endif
+ load_string(g_pos_names[col++], IDS_COL_ATTR);
+#ifndef _NO_EXTENSIONS
+ load_string(g_pos_names[col++], IDS_COL_SEC);
+#endif
}
-void show_frame(HWND hwndParent, int cmdshow)
+static void show_frame(HWND hwndParent, int cmdshow, LPCTSTR path)
{
- TCHAR path[MAX_PATH];
+ const static TCHAR sMDICLIENT[] = {'M','D','I','C','L','I','E','N','T','\0'};
+
+ 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);
/* create main window */
- Globals.hMainWnd = CreateWindowEx(0, (LPCTSTR)(int)Globals.hframeClass, TEXT("Wine File"), WS_OVERLAPPEDWINDOW,
+ Globals.hMainWnd = CreateWindowEx(0, (LPCTSTR)(int)Globals.hframeClass, RS(b1,IDS_WINE_FILE), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwndParent, Globals.hMenuFrame, Globals.hInstance, 0/*lpParam*/);
- Globals.hmdiclient = CreateWindowEx(0, TEXT("MDICLIENT"), NULL,
+ Globals.hmdiclient = CreateWindowEx(0, sMDICLIENT, NULL,
WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
0, 0, 0, 0,
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);
+ CheckMenuItem(Globals.hMenuOptions, ID_VIEW_DRIVE_BAR, MF_BYCOMMAND|MF_CHECKED);
- drivebarBtn.fsStyle = BTNS_BUTTON;
-
-#ifndef _NO_EXTENSIONS
-#ifdef __linux__
- /* insert unix file system button */
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("/\0"));
-
- drivebarBtn.idCommand = ID_DRIVE_UNIX_FS;
- SendMessage(Globals.hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
- drivebarBtn.iString++;
-#endif
-#ifdef _SHELL_FOLDERS
- /* insert shell namespace button */
- SendMessage(Globals.hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("Shell\0"));
-
- 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;
InitInstance(hinstance);
-#ifndef _ROS_ // don't maximize if being called from the ROS desktop
if (cmdshow == SW_SHOWNORMAL)
/*TODO: read window placement from registry */
cmdshow = SW_MAXIMIZE;
-#endif
- 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(WINEFILEFRAME))
+ 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;
}