[2/2] explorer: add a navbar to explorer

Jay Yang jkelleyy at gmail.com
Fri Jun 3 16:05:41 CDT 2011


---
 programs/explorer/explorer.c  |  189 ++++++++++++++++++++++++++++++++++++++++-
 programs/explorer/explorer.rc |    1 +
 programs/explorer/resource.h  |    1 +
 3 files changed, 188 insertions(+), 3 deletions(-)

diff --git a/programs/explorer/explorer.c b/programs/explorer/explorer.c
index 2c84ae9..a07eea8 100644
--- a/programs/explorer/explorer.c
+++ b/programs/explorer/explorer.c
@@ -35,17 +35,34 @@
 #include <windowsx.h>
 #include <shobjidl.h>
 #include <shlobj.h>
+#include <commoncontrols.h>
   WINE_DEFAULT_DEBUG_CHANNEL(explorer);
  #define EXPLORER_INFO_INDEX 0
 +#define NAVBAR_HEIGHT 24
+
 #define DEFAULT_WIDTH 640
 #define DEFAULT_HEIGHT 480
 +#define BACK_BUTTON_INDEX 0
+#define FORWARD_BUTTON_INDEX 1
+#define UP_BUTTON_INDEX 28
+
+/*From shell32*/
+#define IDB_TB_LARGE_LIGHT 214
+
+
 static const WCHAR ExplorerControlClassName[] = {'W','I','N','E','_','E','X','P','L','O','R','E','R','_','C','O','N','T','R','O','L','\0'};
 static const WCHAR ExplorerClassName[] = {'W','I','N','E','_','E','X','P','L','O','R','E','R','\0'};
+static const WCHAR BackButtonName[] = {'B','a','c','k','\0'};
+static const WCHAR ForwardButtonName[] = {'F','o','w','a','r','d','\0'};
+static const WCHAR UpButtonName[] = {'U','p','\0'};
+static const WCHAR PathBoxName[] = {'\0'};
+
+static HICON backButtonIcon, forwardButtonIcon, upButtonIcon;
  HINSTANCE explorer_hInstance;
 @@ -58,18 +75,121 @@ typedef struct parametersTAG {
 typedef struct
 {
     IExplorerBrowser *browser;
+    HWND backButton,forwardButton,upButton,pathBox,goButton;
 } ExplorerInfo;
 +typedef struct
+{
+    IExplorerBrowserEvents IExplorerBrowserEvents_iface;
+    ExplorerInfo* info;
+    LONG ref;
+} IExplorerBrowserEventsImpl;
+
+enum
+{
+    BACK_BUTTON,FORWARD_BUTTON,UP_BUTTON,GO_BUTTON
+};
+
+static IExplorerBrowserEventsImpl *impl_from_IExplorerBrowserEvents(IExplorerBrowserEvents *iface)
+{
+    return CONTAINING_RECORD(iface, IExplorerBrowserEventsImpl, IExplorerBrowserEvents_iface);
+}
+
+static HRESULT WINAPI IExplorerBrowserEventsImpl_fnQueryInterface(IExplorerBrowserEvents *iface, REFIID riid, void **ppvObject)
+{
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IExplorerBrowserEventsImpl_fnAddRef(IExplorerBrowserEvents *iface)
+{
+    IExplorerBrowserEventsImpl *This = impl_from_IExplorerBrowserEvents(iface);
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IExplorerBrowserEventsImpl_fnRelease(IExplorerBrowserEvents *iface)
+{
+    IExplorerBrowserEventsImpl *This = impl_from_IExplorerBrowserEvents(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+    if(!ref)
+        HeapFree(GetProcessHeap(),0,This);
+    return ref;
+}
+
+static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnNavigationComplete(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidl)
+{
+    IExplorerBrowserEventsImpl *This = impl_from_IExplorerBrowserEvents(iface);
+    WCHAR path[MAX_PATH];
+    if(SHGetPathFromIDListW(pidl,path))
+        SetWindowTextW(This->info->pathBox,path);
+    return S_OK;
+}
+
+static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnNavigationFailed(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidl)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnNavigationPending(IExplorerBrowserEvents *iface, PCIDLIST_ABSOLUTE pidl)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI IExplorerBrowserEventsImpl_fnOnViewCreated(IExplorerBrowserEvents *iface, IShellView *psv)
+{
+    return S_OK;
+}
+
+static IExplorerBrowserEventsVtbl vt_IExplorerBrowserEvents =
+{
+    IExplorerBrowserEventsImpl_fnQueryInterface,
+    IExplorerBrowserEventsImpl_fnAddRef,
+    IExplorerBrowserEventsImpl_fnRelease,
+    IExplorerBrowserEventsImpl_fnOnNavigationPending,
+    IExplorerBrowserEventsImpl_fnOnViewCreated,
+    IExplorerBrowserEventsImpl_fnOnNavigationComplete,
+    IExplorerBrowserEventsImpl_fnOnNavigationFailed
+};
+
+static IExplorerBrowserEvents *MakeExplorerEvents(ExplorerInfo *info)
+{
+    IExplorerBrowserEventsImpl *ret
+        = HeapAlloc(GetProcessHeap(), 0, sizeof(IExplorerBrowserEventsImpl));
+    ret->IExplorerBrowserEvents_iface.lpVtbl = &vt_IExplorerBrowserEvents;
+    ret->info = info;
+    IExplorerBrowserEvents_AddRef(&ret->IExplorerBrowserEvents_iface);
+    return &ret->IExplorerBrowserEvents_iface;
+}
+
+static void LoadNavbarIcons(void)
+{
+    HINSTANCE shell32_hInstance = GetModuleHandleA("shell32.dll");
+    IImageList* navbarIcons;
+    HIMAGELIST hNavbarIcons
+        = ImageList_LoadImageW(shell32_hInstance,
+                               (LPCWSTR)MAKEINTRESOURCE(IDB_TB_LARGE_LIGHT),
+                               NAVBAR_HEIGHT,0,CLR_NONE,IMAGE_BITMAP,0);
+    HIMAGELIST_QueryInterface(hNavbarIcons,&IID_IImageList,
+                              (void**)&navbarIcons);
+    IImageList_GetIcon(navbarIcons,BACK_BUTTON_INDEX,0,&backButtonIcon);
+    IImageList_GetIcon(navbarIcons,FORWARD_BUTTON_INDEX,0,&forwardButtonIcon);
+    IImageList_GetIcon(navbarIcons,UP_BUTTON_INDEX,0,&upButtonIcon);
+}
+
 static void MakeExplorerWindow(IShellFolder* startFolder, HINSTANCE hInstance)
 {
     RECT explorerRect;
     HWND window;
     FOLDERSETTINGS fs;
+    IExplorerBrowserEvents *events;
     ExplorerInfo *info;
     HRESULT hres;
+    DWORD cookie;
     WCHAR explorerTitle[100];
+    WCHAR goButtonName[100];
     LoadStringW(hInstance,IDS_EXPLORER_TITLE,explorerTitle,
                 sizeof(explorerTitle)/sizeof(WCHAR));
+    LoadStringW(hInstance,IDS_EXPLORER_GO,goButtonName,
+                sizeof(goButtonName)/sizeof(WCHAR));
     info = HeapAlloc(GetProcessHeap(),0,sizeof(ExplorerInfo));
     if(!info)
     {
@@ -91,28 +211,64 @@ static void MakeExplorerWindow(IShellFolder* startFolder, HINSTANCE hInstance)
     fs.ViewMode = FVM_DETAILS;
     fs.fFlags = FWF_AUTOARRANGE;
     explorerRect.left = 0;
-    explorerRect.top = 0;
+    explorerRect.top = NAVBAR_HEIGHT;
     explorerRect.right = DEFAULT_WIDTH;
     explorerRect.bottom = DEFAULT_HEIGHT;
      IExplorerBrowser_Initialize(info->browser,window,&explorerRect,&fs);
     IExplorerBrowser_SetOptions(info->browser,EBO_SHOWFRAMES);
+    events = MakeExplorerEvents(info);
+    IExplorerBrowser_Advise(info->browser,events,&cookie);
     SetWindowLongPtrW(window,EXPLORER_INFO_INDEX,(LONG)info);
+    /*setup navbar*/
+    info->backButton = CreateWindowW(WC_BUTTONW,BackButtonName,
+                                     WS_CHILD | WS_VISIBLE | BS_ICON,0,0,
+                                     NAVBAR_HEIGHT,NAVBAR_HEIGHT,window,
+                                     (HMENU)BACK_BUTTON,hInstance,NULL);
+    info->forwardButton = CreateWindowW(WC_BUTTONW,ForwardButtonName,
+                                        WS_CHILD | WS_VISIBLE | BS_ICON,
+                                        NAVBAR_HEIGHT,0,NAVBAR_HEIGHT,
+                                        NAVBAR_HEIGHT,window,
+                                        (HMENU)FORWARD_BUTTON,hInstance,NULL);
+    info->upButton = CreateWindowW(WC_BUTTONW,UpButtonName,
+                                   WS_CHILD | WS_VISIBLE | BS_ICON,
+                                   2*NAVBAR_HEIGHT,0,NAVBAR_HEIGHT,
+                                   NAVBAR_HEIGHT,window,(HMENU)UP_BUTTON,
+                                   hInstance,NULL);
+    SendMessageW(info->backButton,BM_SETIMAGE,IMAGE_ICON,
+                 (LPARAM)backButtonIcon);
+    SendMessageW(info->forwardButton,BM_SETIMAGE,IMAGE_ICON,
+                 (LPARAM)forwardButtonIcon);
+    SendMessageW(info->upButton,BM_SETIMAGE,IMAGE_ICON,(LPARAM)upButtonIcon);
+    info->pathBox = CreateWindowW(WC_EDITW,PathBoxName,WS_CHILD | WS_VISIBLE,
+                                  3*NAVBAR_HEIGHT,0,640-4*NAVBAR_HEIGHT,
+                                  NAVBAR_HEIGHT,window,NULL,hInstance,NULL);
+    info->goButton = CreateWindowW(WC_BUTTONW,goButtonName,
+                                   WS_CHILD | WS_VISIBLE,640-NAVBAR_HEIGHT,0,
+                                   NAVBAR_HEIGHT,NAVBAR_HEIGHT,window,
+                                   (HMENU)GO_BUTTON,hInstance,NULL);
     IExplorerBrowser_BrowseToObject(info->browser,(IUnknown*)startFolder,
                                     SBSP_ABSOLUTE);
     ShowWindow(window,SW_SHOWDEFAULT);
     UpdateWindow(window);
+    IExplorerBrowserEvents_Release(events);
 }
  static void UpdateWindowSize(ExplorerInfo *info, int height, int width)
 {
     RECT newRect;
-    int pathBoxWidth = width;
+    int pathBoxWidth = width-4*NAVBAR_HEIGHT;
     newRect.left = 0;
-    newRect.top = 0;
+    newRect.top = NAVBAR_HEIGHT;
     newRect.right = width;
     newRect.bottom = height;
     IExplorerBrowser_SetRect(info->browser,NULL,newRect);
+    if(pathBoxWidth<0)
+        pathBoxWidth = 0;
+    SetWindowPos(info->pathBox,0,3*NAVBAR_HEIGHT,0,
+                 pathBoxWidth,NAVBAR_HEIGHT,0);
+    SetWindowPos(info->goButton,0,width-NAVBAR_HEIGHT,0,
+                 NAVBAR_HEIGHT,NAVBAR_HEIGHT,0);
 }
  static void DoExit(int code)
@@ -200,6 +356,32 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
         IExplorerBrowser_Release(browser);
         HeapFree(GetProcessHeap(),0,info);
         break;
+    case WM_COMMAND:
+        switch(wParam)
+        {
+        case BACK_BUTTON:
+            IExplorerBrowser_BrowseToObject(browser,NULL,SBSP_NAVIGATEBACK);
+            break;
+        case FORWARD_BUTTON:
+            IExplorerBrowser_BrowseToObject(browser,NULL,SBSP_NAVIGATEFORWARD);
+            break;
+        case UP_BUTTON:
+            IExplorerBrowser_BrowseToObject(browser,NULL,SBSP_PARENT);
+            break;
+        case GO_BUTTON:
+            {
+                WCHAR path[MAX_PATH];
+                PIDLIST_ABSOLUTE pidl;
+                *((WORD*)path)=MAX_PATH;
+                /*fix buffer overflow*/
+                SendMessageW(info->pathBox,EM_GETLINE,0,(LPARAM)path);
+                pidl = ILCreateFromPathW(path);
+                IExplorerBrowser_BrowseToIDList(browser,pidl,SBSP_ABSOLUTE);
+                ILFree(pidl);
+                break;
+            }
+        }
+        break;
     case WM_SIZE:
         UpdateWindowSize(info,HIWORD(lParam),LOWORD(lParam));
         break;
@@ -391,6 +573,7 @@ int WINAPI wWinMain(HINSTANCE hinstance,
             ReleaseMutex(mutex);
         ExitProcess(EXIT_FAILURE);
     }
+    LoadNavbarIcons();
     windowClass.cbSize = sizeof(WNDCLASSEXW);
     windowClass.style = 0;
     windowClass.cbClsExtra = 0;
diff --git a/programs/explorer/explorer.rc b/programs/explorer/explorer.rc
index 8fa81c6..b026f01 100644
--- a/programs/explorer/explorer.rc
+++ b/programs/explorer/explorer.rc
@@ -23,4 +23,5 @@
 STRINGTABLE
 {
 	IDS_EXPLORER_TITLE	"Wine Explorer"
+	IDS_EXPLORER_GO		"Go"
 }
diff --git a/programs/explorer/resource.h b/programs/explorer/resource.h
index f3813b0..ea7bbaa 100644
--- a/programs/explorer/resource.h
+++ b/programs/explorer/resource.h
@@ -22,5 +22,6 @@
 #define __WINE_EXPLORER_RESOURCE_H
  #define IDS_EXPLORER_TITLE 1
+#define IDS_EXPLORER_GO 2
  #endif
-- 
1.7.5.2




More information about the wine-patches mailing list