oleview: Added TypeLib Viewer base

Piotr Caban piotr.caban at gmail.com
Fri Jun 30 10:29:56 CDT 2006


Hi,

Changelog:
 - Added TypeLib Viewer base
 - Fixed multiple instance of pane window functionality
 - Added field with TypeLib path to ITEM_INFO structure

 programs/oleview/En.rc       |   18 ++++++
 programs/oleview/Makefile.in |    3 +
 programs/oleview/main.h      |   20 ++++++-
 programs/oleview/oleview.c   |    3 +
 programs/oleview/pane.c      |   10 +++
 programs/oleview/resource.h  |    6 ++
 programs/oleview/tree.c      |   37 ++++++++----
 programs/oleview/typelib.c   |  126
++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 204 insertions(+), 19 deletions(-)

--
Piotr

-------------- next part --------------
diff --git a/programs/oleview/En.rc b/programs/oleview/En.rc
index 93ebcdb..92f2fa8 100644
--- a/programs/oleview/En.rc
+++ b/programs/oleview/En.rc
@@ -71,6 +71,22 @@ IDM_MENU MENU
     }
 }
 
+IDM_TYPELIB MENU
+{
+    POPUP "&File"
+    {
+        MENUITEM "&Save as",    IDM_SAVEAS
+        MENUITEM "&Close",  IDM_CLOSE
+    }
+    POPUP "&View"
+    {
+        MENUITEM "&Group by type kind", IDM_GROUP
+        MENUITEM SEPARATOR
+        MENUITEM "&Toolbar",    IDM_TOOLBAR
+        MENUITEM "&Status Bar", IDM_STATUSBAR
+    }
+}
+
 STRINGTABLE
 {
     IDS_APPNAME            "OleView"
@@ -78,6 +94,7 @@ STRINGTABLE
     IDS_READY              "Ready"
     IDS_ABOUT              "OleView - OLE/COM Object Viewer"
     IDS_ABOUTVER           "version 1.0"
+    IDS_TYPELIBTITLE       "ITypeLib viewer"
 
     IDM_BIND,              "Bind to file via a File Moniker"
     IDM_TYPELIB,           "Open a TypeLib file and view the contents"
@@ -185,3 +202,4 @@ FONT 8, "MS Shell Dlg"
     PUSHBUTTON  "&GetSizeMax", IDC_GETSIZEMAX_BUTTON, 6, 49, 50, 14
     LTEXT   "???", IDC_GETSIZEMAX, 60, 52, 145, 8
 }
+
diff --git a/programs/oleview/Makefile.in b/programs/oleview/Makefile.in
index 818edc0..2df5004 100644
--- a/programs/oleview/Makefile.in
+++ b/programs/oleview/Makefile.in
@@ -13,7 +13,8 @@ C_SRCS = \
 	interface.c \
 	oleview.c \
 	pane.c \
-	tree.c
+	tree.c \
+	typelib.c
 
 RC_SRCS = rsrc.rc
 RC_BINSRC = rsrc.rc
diff --git a/programs/oleview/main.h b/programs/oleview/main.h
index 2850d45..a9b3c49 100644
--- a/programs/oleview/main.h
+++ b/programs/oleview/main.h
@@ -54,6 +54,7 @@ typedef struct
     HWND hToolBar;
     HWND hTree;
     HWND hDetails;
+    HWND hTypeLibWnd;
     HINSTANCE hMainInst;
     BOOL bExpert;
     DWORD dwClsCtx;
@@ -89,6 +90,7 @@ typedef struct
     CHAR cFlag;
     WCHAR info[MAX_LOAD_STRING];
     WCHAR clsid[MAX_LOAD_STRING];
+    WCHAR path[MAX_LOAD_STRING];
     BOOL loaded;
     IUnknown *pU;
 }ITEM_INFO;
@@ -100,8 +102,16 @@ typedef struct
     HWND hReg;
 }DETAILS;
 
+typedef struct
+{
+    HWND hPaneWnd;
+    HWND hTree;
+    HWND hEdit;
+}TYPELIB;
+
 extern GLOBALS globals;
 extern TREE tree;
+extern TYPELIB typelib;
 
 /* Predefinitions: */
 /* details.c */
@@ -113,10 +123,11 @@ void RefreshMenu(HTREEITEM item);
 
 /* pane.c */
 BOOL CreatePanedWindow(HWND hWnd, HWND *hWndCreated, HINSTANCE hInst);
+BOOL PaneRegisterClass(void);
 void SetLeft(HWND hParent, HWND hWnd);
 void SetRight(HWND hParent, HWND hWnd);
 
-/* tree.h */
+/* tree.c */
 void EmptyTree(void);
 void AddTreeEx(void);
 void AddTree(void);
@@ -125,6 +136,11 @@ BOOL CreateRegPath(HTREEITEM item, WCHAR
 void CreateInst(HTREEITEM item, WCHAR *wszMachineName);
 void ReleaseInst(HTREEITEM item);
 
-/* interface.h */
+/* typelib.c */
+BOOL CreateTypeLibWindow(HINSTANCE hInst);
+BOOL TypeLibRegisterClass(void);
+
+/* interface.c */
 BOOL IsInterface(HTREEITEM item);
 void InterfaceViewer(HTREEITEM item);
+
diff --git a/programs/oleview/oleview.c b/programs/oleview/oleview.c
index c0b17ba..73980b2 100644
--- a/programs/oleview/oleview.c
+++ b/programs/oleview/oleview.c
@@ -383,6 +383,7 @@ int MenuCommand(WPARAM wParam, HWND hWnd
         case IDM_VIEW:
             hSelect = TreeView_GetSelection(globals.hTree);
             if(IsInterface(hSelect)) InterfaceViewer(hSelect);
+            else CreateTypeLibWindow(globals.hMainInst);
             break;
         case IDM_EXIT:
             DestroyWindow(hWnd);
@@ -408,6 +409,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT
     {
         case WM_CREATE:
             OleInitialize(NULL);
+            PaneRegisterClass();
+            TypeLibRegisterClass();
             if(!CreatePanedWindow(hWnd, &globals.hPaneWnd, globals.hMainInst))
                 PostQuitMessage(0);
             SetLeft(globals.hPaneWnd, CreateTreeWindow(globals.hMainInst));
diff --git a/programs/oleview/pane.c b/programs/oleview/pane.c
index 6e5ab62..6943db4 100644
--- a/programs/oleview/pane.c
+++ b/programs/oleview/pane.c
@@ -119,11 +119,10 @@ LRESULT CALLBACK PaneProc(HWND hWnd, UIN
     return 0;
 }
 
-BOOL CreatePanedWindow(HWND hWnd, HWND *hWndCreated, HINSTANCE hInst)
+BOOL PaneRegisterClass(void)
 {
     WNDCLASS wcc;
     const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };
-    PANE *pane;
 
     memset(&wcc, 0, sizeof(WNDCLASS));
     wcc.lpfnWndProc = PaneProc;
@@ -132,6 +131,13 @@ BOOL CreatePanedWindow(HWND hWnd, HWND *
 
     if(!RegisterClass(&wcc))
         return FALSE;
+    return TRUE;
+}
+
+BOOL CreatePanedWindow(HWND hWnd, HWND *hWndCreated, HINSTANCE hInst)
+{
+    const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };
+    PANE *pane;
 
     pane = HeapAlloc(GetProcessHeap(), 0, sizeof(PANE));
     *hWndCreated = CreateWindow(wszPaneClass, NULL, WS_CHILD|WS_VISIBLE,
diff --git a/programs/oleview/resource.h b/programs/oleview/resource.h
index 83fe9e9..9b1aaa1 100644
--- a/programs/oleview/resource.h
+++ b/programs/oleview/resource.h
@@ -23,6 +23,7 @@ #define IDS_APPTITLE               2
 #define IDM_MENU                   3
 #define IDB_TOOLBAR                4
 #define IDA_OLEVIEW                5
+#define IDS_TYPELIBTITLE           6
 
 #define IDS_READY                  10
 #define IDS_ABOUT                  20
@@ -91,3 +92,8 @@ #define IDC_ISDIRTY                1041
 #define IDC_GETSIZEMAX             1042
 #define IDC_ISDIRTY_BUTTON         1043
 #define IDC_GETSIZEMAX_BUTTON      1044
+
+#define IDM_SAVEAS                 3001
+#define IDM_CLOSE                  3002
+#define IDM_GROUP                  3003
+
diff --git a/programs/oleview/tree.c b/programs/oleview/tree.c
index aa229db..117df6d 100644
--- a/programs/oleview/tree.c
+++ b/programs/oleview/tree.c
@@ -35,8 +35,9 @@ static const WCHAR wszTypeLib[] = { 'T',
 static const WCHAR wszInterface[] = { 'I','n','t','e','r','f','a','c','e','\\','\0' };
 static const WCHAR wszComponentCategories[] = { 'C','o','m','p','o','n','e','n','t',
     ' ','C','a','t','e','g','o','r','i','e','s','\\','\0' };
+static const WCHAR wszGetPath[] = { '0','\\','w','i','n','3','2','\0' };
 
-LPARAM CreateITEM_INFO(INT flag, const WCHAR *info, const WCHAR *clsid)
+LPARAM CreateITEM_INFO(INT flag, const WCHAR *info, const WCHAR *clsid, const WCHAR *path)
 {
     ITEM_INFO *reg;
 
@@ -46,6 +47,7 @@ LPARAM CreateITEM_INFO(INT flag, const W
     reg->cFlag = flag;
     lstrcpyW(reg->info, info);
     if(clsid) lstrcpyW(reg->clsid, clsid);
+    if(path) lstrcpyW(reg->path, path);
 
     return (LPARAM)reg;
 }
@@ -170,7 +172,7 @@ #define CASE_ERR(i) case i: \
             lstrcpyW(wszRegPath, wszInterface);
             lstrcpyW(&wszRegPath[lstrlenW(wszRegPath)], ((ITEM_INFO *)tvi.lParam)->clsid);
             U(tvis).item.lParam = CreateITEM_INFO(REGTOP|INTERFACE|REGPATH,
-                    wszRegPath, ((ITEM_INFO *)tvi.lParam)->clsid);
+                    wszRegPath, ((ITEM_INFO *)tvi.lParam)->clsid, NULL);
             SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
         }
         hCur = TreeView_GetNextSibling(globals.hTree, hCur);
@@ -294,7 +296,7 @@ void AddCOMandAll(void)
             U(tvis).item.pszText = buffer;
         else U(tvis).item.pszText = valName;
     
-        U(tvis).item.lParam = CreateITEM_INFO(REGPATH|SHOWALL, valName, valName);
+        U(tvis).item.lParam = CreateITEM_INFO(REGPATH|SHOWALL, valName, valName, NULL);
         if(tvis.hParent) SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
 
         if(RegOpenKey(hCurKey, wszImplementedCategories, &hInfo) == ERROR_SUCCESS)
@@ -318,7 +320,7 @@ void AddCOMandAll(void)
                     memmove(&valName[6], valName, sizeof(WCHAR[MAX_LOAD_STRING-6]));
                     memmove(valName, wszCLSID, sizeof(WCHAR[6]));
                     U(tvis).item.lParam = CreateITEM_INFO(REGTOP|REGPATH|SHOWALL,
-                            valName, &valName[6]);
+                            valName, &valName[6], NULL);
 
                     SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
                     break;
@@ -366,7 +368,7 @@ void AddApplicationID(void)
 
         RegCloseKey(hCurKey);
 
-        U(tvis).item.lParam = CreateITEM_INFO(REGPATH, valName, valName);
+        U(tvis).item.lParam = CreateITEM_INFO(REGPATH, valName, valName, NULL);
         SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
     }
     RegCloseKey(hKey);
@@ -377,11 +379,12 @@ void AddApplicationID(void)
 void AddTypeLib(void)
 {
     TVINSERTSTRUCT tvis;
-    HKEY hKey, hCurKey, hInfoKey;
+    HKEY hKey, hCurKey, hInfoKey, hPath;
     WCHAR valName[MAX_LOAD_STRING];
     WCHAR valParent[MAX_LOAD_STRING];
     WCHAR buffer[MAX_LOAD_STRING];
     WCHAR wszVer[MAX_LOAD_STRING];
+    WCHAR wszPath[MAX_LOAD_STRING];
     const WCHAR wszFormat[] = { ' ','(','%','s',' ','%','s',')','\0' };
     const WCHAR wszFormat2[] = { '%','s','\\','%','s','\0' };
     LONG lenBuffer;
@@ -421,13 +424,18 @@ void AddTypeLib(void)
 
                 wsprintfW(&buffer[lstrlenW(buffer)], wszFormat, wszVer, valName);
                 U(tvis).item.pszText = buffer;
+
+                lenBuffer = MAX_LOAD_STRING;
+                RegOpenKey(hInfoKey, wszGetPath, &hPath);
+                RegQueryValue(hPath, NULL, wszPath, &lenBuffer);
+                RegCloseKey(hPath);
             }
             else U(tvis).item.pszText = valName;
 
             RegCloseKey(hInfoKey);
 
             wsprintfW(wszVer, wszFormat2, valParent, valName);
-            U(tvis).item.lParam = CreateITEM_INFO(REGPATH, wszVer, valParent);
+            U(tvis).item.lParam = CreateITEM_INFO(REGPATH, wszVer, valParent, wszPath);
 
             SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
         }
@@ -471,7 +479,7 @@ void AddInterfaces(void)
 
         RegCloseKey(hCurKey);
 
-        U(tvis).item.lParam = CreateITEM_INFO(REGPATH|INTERFACE, valName, valName);
+        U(tvis).item.lParam = CreateITEM_INFO(REGPATH|INTERFACE, valName, valName, NULL);
         SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
     }
 
@@ -520,7 +528,7 @@ void AddComponentCategories(void)
 
         RegCloseKey(hCurKey);
 
-        U(tvis).item.lParam = CreateITEM_INFO(REGTOP, valName, valName);
+        U(tvis).item.lParam = CreateITEM_INFO(REGTOP, valName, valName, NULL);
         SendMessage(globals.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
     }
 
@@ -544,17 +552,17 @@ void AddBaseEntries(void)
 
     LoadString(globals.hMainInst, IDS_TREE_I, U(tvis).item.pszText,
             sizeof(WCHAR[MAX_LOAD_STRING]));
-    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszInterface, NULL);
+    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszInterface, NULL, NULL);
     tree.hI = TreeView_InsertItem(globals.hTree, &tvis);
 
     LoadString(globals.hMainInst, IDS_TREE_TL, U(tvis).item.pszText,
             sizeof(WCHAR[MAX_LOAD_STRING]));
-    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszTypeLib, NULL);
+    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszTypeLib, NULL, NULL);
     tree.hTL = TreeView_InsertItem(globals.hTree, &tvis);
 
     LoadString(globals.hMainInst, IDS_TREE_AID, U(tvis).item.pszText,
             sizeof(WCHAR[MAX_LOAD_STRING]));
-    U(tvis).item.lParam = CreateITEM_INFO(REGTOP|REGPATH, wszAppID, NULL);
+    U(tvis).item.lParam = CreateITEM_INFO(REGTOP|REGPATH, wszAppID, NULL, NULL);
     tree.hAID = TreeView_InsertItem(globals.hTree, &tvis);
 
     LoadString(globals.hMainInst, IDS_TREE_OC, U(tvis).item.pszText,
@@ -566,7 +574,7 @@ void AddBaseEntries(void)
     tvis.hParent = tree.hOC;
     LoadString(globals.hMainInst, IDS_TREE_AO, U(tvis).item.pszText,
             sizeof(WCHAR[MAX_LOAD_STRING]));
-    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszCLSID, NULL);
+    U(tvis).item.lParam = CreateITEM_INFO(REGTOP, wszCLSID, NULL, NULL);
     tree.hAO = TreeView_InsertItem(globals.hTree, &tvis);
 
     LoadString(globals.hMainInst, IDS_TREE_CLO, U(tvis).item.pszText,
@@ -580,7 +588,8 @@ void AddBaseEntries(void)
 
     LoadString(globals.hMainInst, IDS_TREE_GBCC, U(tvis).item.pszText,
             sizeof(WCHAR[MAX_LOAD_STRING]));
-    U(tvis).item.lParam = CreateITEM_INFO(REGTOP|REGPATH, wszComponentCategories, NULL);
+    U(tvis).item.lParam = CreateITEM_INFO(REGTOP|REGPATH,
+            wszComponentCategories, NULL, NULL);
     tree.hGBCC = TreeView_InsertItem(globals.hTree, &tvis);
 
     SendMessage(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)tree.hOC);
diff --git a/programs/oleview/typelib.c b/programs/oleview/typelib.c
new file mode 100644
index 0000000..ca9323b
--- /dev/null
+++ b/programs/oleview/typelib.c
@@ -0,0 +1,126 @@
+/*
+ * OleView (typelib.c)
+ *
+ * Copyright 2006 Piotr Caban
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "main.h"
+
+TYPELIB typelib;
+static const WCHAR wszTypeLib[] = { 'T','Y','P','E','L','I','B','\0' };
+
+void PopulateTree(void)
+{
+    TVITEM tvi;
+    TVINSERTSTRUCT tvis;
+    ITypeLib *pTypeLib;
+    INT count, i;
+    BSTR bstrName;
+
+    memset(&tvi, 0, sizeof(TVITEM));
+    tvi.hItem = TreeView_GetSelection(globals.hTree);
+
+    U(tvis).item.mask = TVIF_TEXT|TVIF_CHILDREN;
+    U(tvis).item.cChildren = 1;
+    tvis.hInsertAfter = (HTREEITEM)TVI_LAST;
+    tvis.hParent = TVI_ROOT;
+
+    SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);
+    if(FAILED(LoadTypeLib(((ITEM_INFO*)tvi.lParam)->path, &pTypeLib))) return;
+
+    count = ITypeLib_GetTypeInfoCount(pTypeLib);
+
+    for(i=-1; i<count; i++) {
+        ITypeLib_GetDocumentation(pTypeLib, i, &bstrName, NULL, NULL, NULL);
+
+        U(tvis).item.cchTextMax = SysStringLen(bstrName);
+        U(tvis).item.pszText = bstrName;
+
+        if(i==-1)
+            tvis.hParent = (HTREEITEM)SendMessage(typelib.hTree,
+                    TVM_INSERTITEM, 0, (LPARAM)&tvis);
+        else SendMessage(typelib.hTree, TVM_INSERTITEM, 0, (LPARAM)&tvis);
+
+        SysFreeString(bstrName);
+    }
+    SendMessage(typelib.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
+
+    ITypeLib_Release(pTypeLib);
+}
+
+LRESULT CALLBACK TypeLibProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    switch(uMsg)
+    {
+        case WM_CREATE:
+        {
+            if(!CreatePanedWindow(hWnd, &typelib.hPaneWnd, globals.hMainInst))
+                DestroyWindow(hWnd);
+            typelib.hTree = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, NULL,
+                    WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
+                    0, 0, 0, 0, typelib.hPaneWnd, NULL, globals.hMainInst, NULL);
+            typelib.hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, NULL,
+                    WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_READONLY|WS_HSCROLL|WS_VSCROLL,
+                    0, 0, 0, 0, typelib.hPaneWnd, NULL, globals.hMainInst, NULL);
+
+            SetLeft(typelib.hPaneWnd, typelib.hTree);
+            SetRight(typelib.hPaneWnd, typelib.hEdit);
+
+            PopulateTree();
+            break;
+        }
+        case WM_SIZE:
+            MoveWindow(typelib.hPaneWnd, 0, 0,
+                    LOWORD(lParam), HIWORD(lParam), TRUE);
+            break;
+        case WM_DESTROY:
+            break;
+        default:
+            return DefWindowProc(hWnd, uMsg, wParam, lParam);
+    }
+    return 0;
+}
+
+BOOL TypeLibRegisterClass(void)
+{
+    WNDCLASS wcc;
+
+    memset(&wcc, 0, sizeof(WNDCLASS));
+    wcc.lpfnWndProc = TypeLibProc;
+    wcc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+    wcc.lpszMenuName = MAKEINTRESOURCE(IDM_TYPELIB);
+    wcc.lpszClassName = wszTypeLib;
+
+    if(!RegisterClass(&wcc))
+        return FALSE;
+
+    return TRUE;
+}
+
+BOOL CreateTypeLibWindow(HINSTANCE hInst)
+{
+    WCHAR wszTitle[MAX_LOAD_STRING];
+    LoadString(hInst, IDS_TYPELIBTITLE, wszTitle, sizeof(WCHAR[MAX_LOAD_STRING]));
+
+    globals.hTypeLibWnd = CreateWindow(wszTypeLib, wszTitle,
+            WS_OVERLAPPEDWINDOW|WS_VISIBLE,
+            CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInst, NULL);
+
+    if(!globals.hTypeLibWnd) return FALSE;
+    return TRUE;
+}
+


More information about the wine-patches mailing list